image

Part 0 - Topic introduction

People always use a lot of personal pronouns to avoid repeating someone’s names time and time again. Different people may use different personal pronouns for different weight in different situation to demonstrate different meanings and emotions. What about the situations in presidents’ Inaugural Speeches?

Part 1 - Packages preparaion

packages.used=c("RColorBrewer","qdap","ggplot2","reshape2","syuzhet","tm","qdap","reshape2","gridExtra","ggplot2","wordcloud","dplyr","tidytext")

# check packages that need to be installed.
packages.needed=setdiff(packages.used, 
                        intersect(installed.packages()[,1], 
                                  packages.used))
# install additional packages
if(length(packages.needed)>0){
  install.packages(packages.needed, dependencies = TRUE)
}
require(devtools,quietly = T)
install_github('recharts', 'taiyun')

# library packages
library("RColorBrewer",quietly = T)
library("qdap",quietly = T)
library("ggplot2",quietly = T)
library("reshape2",quietly = T)
library("syuzhet",quietly = T)
library("tm",quietly = T)
library("qdap",quietly = T)
library("reshape2",quietly = T)
library("gridExtra",quietly = T)
library("ggplot2",quietly = T)
library("wordcloud",quietly = T)
library("dplyr",quietly = T)
library("tidytext",quietly = T)
library("recharts",quietly = T)

#part of codes are in this R file.
source("../lib/customized_function.R")

Part 2 - Data cleaning

We count the word frequency for each speeches and make this data matrix on which our whole analysis would based.

inaug.list=read.csv("../data/InaugurationInfo.csv", stringsAsFactors = FALSE)
inaug.data=read.table("../data/InauguationDates.txt", stringsAsFactors = FALSE,blank.lines.skip=F,sep= "\t")
mat1<-NULL
for(i in seq(nrow(inaug.list))) {
filename <- paste0("../data/InauguralSpeeches/inaug", 
                     inaug.list$File[i], "-", 
                     inaug.list$Term[i], ".txt")
tx <- readLines(filename,warn=F)
if (i==58) 
{
  tx<-paste(tx, collapse = " ")
  tx_words <- strsplit(tx, split = " ")[[1]]
}
else
tx_words <- strsplit(tx, split = " ")[[1]]
date_pattern2 <- "[a-zA-z]+"
tx_words2 <- grep(tx_words, pattern = date_pattern2, value=T)
tx_log <- grepl(tx_words2, pattern = date_pattern2)
matches <- gregexpr(pattern = date_pattern2, text = tx_words2[tx_log])
tx_words <- unlist(regmatches(tx_words2[tx_log], matches))
tx_words <- unlist(rm_stopwords(tx_words))
mat<-NULL
table<-table(tx_words)
word<-names(table)
n<-unname(table)
matname<-paste(inaug.list$File[i],inaug.list$Term[i])
mat<-cbind(rep(matname,nrow(n)),word,n)
mat1<-rbind(mat1,mat)
}
colnames(mat1)<-c("name","word","n") 
matsort<-mat1[order(as.numeric(mat1[,3]),decreasing = T),]
head(matsort)
     name                     word    n    
[1,] "WilliamHenryHarrison 1" "which" "107"
[2,] "WilliamHenryHarrison 1" "by"    "103"
[3,] "JamesKPolk 1"           "our"   "101"
[4,] "CalvinCoolidge 1"       "we"    "88" 
[5,] "WilliamHenryHarrison 1" "their" "81" 
[6,] "WarrenGHarding 1"       "we"    "80" 

Part 3 - Different president uses personal pronoun for different weight

In this part,we will do a general analysis,to see the general trend and find difference of the weight when divided by different factors.By saying weight,we mean the times one using a certain personal pronoun divided by the total times he using all four types of pronouns.

We divide personal pronouns into 4 types,first person singular form,first person plural form,second person form and third person form.

image
#personal pronoun
first1<-c("I","me","mine","my")
first2<-c("we","our","ours","us")
second<-c("you","your","yours")
third<-c("he","she","it","him","her","his","hers","they","them","their")
personal<-list(first1,first2,second,third)
pp_mat<-matrix(nrow = nrow(inaug.list),ncol = 4)
for(i in seq(nrow(inaug.list))) {
  test<-matsort[matsort[,"name"]==paste(inaug.list$File[i],inaug.list$Term[i]),"word"]
  pp_mat[i,]<-find_personal_pronoun(test)
}
ppname<-NULL
for(i in seq(nrow(inaug.list))) {
ppname[i] <- paste(inaug.list$File[i], inaug.list$Term[i]) }
rownames(pp_mat)<-ppname
colnames(pp_mat)<-c("first1","first2","second","third")
head(pp_mat)
                      first1    first2    second     third
GeorgeWashington 1 0.2222222 0.3333333 0.1111111 0.3333333
GeorgeWashington 2 0.6666667 0.0000000 0.3333333 0.0000000
JohnAdams 1        0.2222222 0.4444444 0.1111111 0.2222222
ThomasJefferson 1  0.2222222 0.3333333 0.1111111 0.3333333
ThomasJefferson 2  0.2500000 0.3750000 0.1250000 0.2500000
JamesMadison 1     0.2857143 0.4285714 0.0000000 0.2857143
pp_mat1<-pp_mat
rownames(pp_mat1)<-seq(1789,2017,4)
pp_mat2<-melt(pp_mat1)
pp_mat3<-melt(pp_mat)
new1<-mat2mat(pp_mat)
a<-ggplot(data.frame(personal_pronoun=new1[,"type"],new1[,"name"],new1[,"prop"]), aes(x=factor(new1[,"name"], levels=unique(new1[,"name"])),y=new1[,"prop"], colour=personal_pronoun,group=personal_pronoun))+ geom_line(size=2) + theme(axis.text.x = element_blank()) + xlab("time with different presidents") + ylab("proportion") 
pp_dat<-data.frame(year=pp_mat2$Var1,proportion=pp_mat2$value,personal_pronoun=pp_mat2$Var2)
b<-ggplot(pp_dat, aes(x = year, y = proportion, fill = personal_pronoun)) +
  geom_area() +
  scale_fill_brewer(palette = "Blues", breaks = rev(c("third","second","first2","first1")))
pp_dat<-data.frame(president=pp_mat3$Var1,proportion=pp_mat2$value,personal_pronoun=pp_mat2$Var2)
c<-ggplot(pp_dat,aes(president,proportion,fill=personal_pronoun))+geom_bar(stat="identity",position="stack")+ggtitle("")+guides(fill=guide_legend(title=NULL))+
  scale_fill_brewer(palette = "Blues")+ theme(axis.text.x = element_blank()) + xlab("time with different presidents")
#grid.arrange(b,c,nrow=2)

Notice:The plot(and some following plots) are interactive by moving your mouse to a certain data point,details can be shown.

3.1 General Trend

x-axis:time (different presidents) y-axis:the weight of a certain kind of personal pronoun being used.

eArea(pp_mat1)

In general

It’s quite reasonable,since presidents come to realize that they should emphasize people’s rights and responsibilities to let people feel that they are being together,the interests of every citizens are closely related to destiny of the United States,rather than just talking about themselves.

3.2 Comparing between different terms

#different term 
avg<-apply(pp_mat,2,mean)
list<-term_sep()
avg_term1<-apply(pp_mat[list[[1]],],2,mean)
avg_term2<-apply(pp_mat[list[[2]],],2,mean)
df1<-data.frame(avg,avg_term1,avg_term2)
dat<-t(df1)
mydat<-melt(dat)
#mydat
mydat<-data.frame(term = mydat$Var1,personal_pronoun = mydat$Var2,proportion=round(mydat$value,2))
ggplot(mydat,aes(term,proportion,fill=personal_pronoun))+geom_bar(stat="identity",position="stack")+ggtitle("")+theme(axis.ticks.length=unit(0.5,'cm'))+guides(fill=guide_legend(title=NULL))+
  scale_fill_brewer(palette = "Blues")

eRadar(xtabs( proportion~ term+personal_pronoun, mydat))

From president’s term 1 to term 2,they tend to use more first person plural form than first person singular form.It’s also reasonable, since the president and the public become familiar to each other,so the president naturally take himself and the public as a whole group.

3.3 Comparing among different parties

#different party
new_inaug.list<-cbind(inaug.list,pp_mat)
first1<-tapply(new_inaug.list$first1,new_inaug.list$Party,mean)
first2<-tapply(new_inaug.list$first2,new_inaug.list$Party,mean)
second<-tapply(new_inaug.list$second,new_inaug.list$Party,mean)
third<-tapply(new_inaug.list$third,new_inaug.list$Party,mean)
#head(new_inaug.list)
#aggregate(new_inaug.list,)
dat<-rbind(unname(first1),unname(first2),unname(second),unname(third))
colnames(dat)<-names(first1)
rownames(dat)<-c("first1","first2","second","third")
mydat<-melt(dat)
mydat<-data.frame(personal_pronoun = mydat$Var1, party = mydat$Var2,proportion=round(mydat$value,2))
ggplot(mydat,aes(party,proportion,fill=personal_pronoun))+geom_bar(stat="identity",position="stack")+ggtitle("")+theme(axis.ticks.length=unit(0.5,'cm'))+guides(fill=guide_legend(title=NULL))+
  scale_fill_brewer(palette = "Blues")+ theme(axis.text.x = element_text(angle = 15, hjust = 0.5, vjust = 0.5))

eRadar(xtabs( proportion~ party+personal_pronoun, mydat))

As the plot shown,Whig used first person singular form and third person most frequently,used first person plural form as well as second person at least frequency.While federalist is almost the opposite.

Part 4 - Analysis on each kind of personal pronoun’s CRAZY FAN

In this part, we switch our analysis from the overall data to some extreme points, to analysis the features about those presidents who use a certain type of personal pronoun at a high frequency,like top 10.

data1<-pp_mat[order(pp_mat[,1],decreasing = T),][1:10,]
data2<-pp_mat[order(pp_mat[,2],decreasing = T),][1:10,]
data3<-pp_mat[order(pp_mat[,3],decreasing = T),][1:10,]
data4<-pp_mat[order(pp_mat[,4],decreasing = T),][1:10,]
new1<-mat2mat(data1)
new2<-mat2mat(data2)
new3<-mat2mat(data3)
new4<-mat2mat(data4)
new1<-data.frame(type=new1[,"type"],name=new1[,"name"],proportion=as.numeric(new1[,"prop"]))
new2<-data.frame(type=new2[,"type"],name=new2[,"name"],proportion=as.numeric(new2[,"prop"]))
new3<-data.frame(type=new3[,"type"],name=new3[,"name"],proportion=as.numeric(new3[,"prop"]))
new4<-data.frame(type=new4[,"type"],name=new4[,"name"],proportion=as.numeric(new4[,"prop"]))
inaug.list=read.csv("../data/InaugurationInfo.csv", stringsAsFactors = FALSE)
inaug.data=read.table("../data/InauguationDates.txt", stringsAsFactors = FALSE,blank.lines.skip=F,sep= "\t")
first1<-c("I","me","mine","my")
first2<-c("we","our","ours","us")
second<-c("you","your","yours")
third<-c("he","she","it","him","her","his","hers","they","them","their")
personal<-list(first1,first2,second,third)
speech.list=read.csv("../data/InaugurationInfo.csv", stringsAsFactors = FALSE)
speech.list$type=c(rep("inaug", nrow(speech.list)))
speech.list$fulltext=NA
sentence.list=NULL

4.1 Top ten using first person singular form

eBar(new1, ~name, ~proportion, ~type)
test<-topic_wc(2,1)
dat<-data.frame(word=test[,"word"],freq=5*as.numeric(test[,"n"]))
#par(mfrow=c(1,2))
eWordcloud(dat[7:65,], namevar = ~word, datavar = ~freq,size = c(600, 600),title = "George Washington & first person singular",rotationRange = c(-1, 1))

test<-topic_wc(2,3)
dat<-data.frame(word=test[,"word"],freq=5*as.numeric(test[,"n"]))
eWordcloud(dat[2:32,], namevar = ~word, datavar = ~freq,size = c(600, 600),title = "George Washington & second person",rotationRange = c(-1, 1))

No.1 “first person singular user” is George Washington(term 2).The 67% personal pronoun George Washington used in his second person is first person singular form. He also used second person quite frequently at about 33%. Along with the word cloud,we can speculate in his speeches,no matter using first singular form or second form,he used words like “administration”,“chief”,it was shown that he took himself as a leader and wanted to express his power to public.

test<-matsort[matsort[,"name"] == "WilliamMcKinley 1",]
test1<-matsort[matsort[,"name"] == "WoodrowWilson 2",]
test2<-matsort[matsort[,"name"] == "JamesBuchanan 1",]
test<-rbind(test,test1,test2)
test<-test[order(as.numeric(test[,3]),decreasing = T),]
test<-test[17:2529,]
dat<-data.frame(word=test[,"word"],freq=test[,"n"])
#par(mfrow=c(1,2))
eWordcloud(dat, namevar = ~word, datavar = ~freq,size = c(600, 600),title = "WilliamMcKinley 1 & WoodrowWilson 2 & JamesBuchanan 1",rotationRange = c(-1, 1))

Except Washington,from No.2 William McKinley(term 1) to No.4 James Buchanan(term 1),they didn’t even use second person.Add their three’s speeches to make the wordcloud,we can hardly find the words demonstrating centralization of power, instead,there are words like “congress”,“fair”,“civil”,“life”,showing more gentle emotion.

4.2 Top ten using first person plural form

eBar(new2, ~name, ~proportion, ~type)
test<-matsort[matsort[,"name"] == "FranklinDRoosevelt 3",]
test1<-matsort[matsort[,"name"] == "TheodoreRoosevelt 1",]
test2<-matsort[matsort[,"name"] == "AndrewJackson 1",]
test3<-matsort[matsort[,"name"] == "AbrahamLincoln 2",]
test4<-matsort[matsort[,"name"] == "WilliamMcKinley 2",]
test5<-matsort[matsort[,"name"] == "FranklinDRoosevelt 4",]
test<-rbind(test,test1,test2,test3,test4,test5)
test<-test[order(as.numeric(test[,3]),decreasing = T),]
test<-test[40:2638,]
dat<-data.frame(word=test[,"word"],freq=test[,"n"])
#par(mfrow=c(1,2))
eWordcloud(dat, namevar = ~word, datavar = ~freq,size = c(600, 600),title = "TOP 6 using first person plural form",rotationRange = c(-1, 1))

For presidents frequently using first person plural form, there exists similar phenomenon.From No.1 Franklin DRoosevelt(term 3) to No.6 Franklin DRoosevelt(term 4),they also make the speeches without using second person.Add their speeches to make the wordcloud,we find similar words showing gentle emotion.

4.3 Top ten using second person

eBar(new3, ~name, ~proportion, ~type)

4.4 Top ten using third person

eBar(new4, ~name, ~proportion, ~type)

4.5 Each personal pronoun’s “Fan Club” feature : positive? negative?

data(positive.words)
data(negative.words)
sentiment_analy<-function(words)
{
      score<-NULL
      # compare words to the dictionaries of positive & negative terms
      positive.matches = match(words, positive.words)
      negative.matches = match(words, negative.words)
      # get the position of the matched term or NA
      # we just want a TRUE/FALSE
      positive_matches = !is.na(positive.matches)
      negative_matches = !is.na(negative.matches)
      score = sum(positive_matches) - sum(negative_matches) 
      return(score)
}
senti_vec<-NULL
for(i in seq(nrow(inaug.list))) {
  test<-matsort[matsort[,"name"]==paste(inaug.list$File[i],inaug.list$Term[i]),"word"]
  senti_vec[i]<-sentiment_analy(test)
}
svname<-NULL
for(i in seq(nrow(inaug.list))) {
svname[i] <- paste(inaug.list$File[i], inaug.list$Term[i]) }
#sentiment vs person
senti_mat<-cbind(ppname,senti_vec)
n1<-match(rownames(data1),ppname)
n2<-match(rownames(data2),ppname)
n3<-match(rownames(data3),ppname)
n4<-match(rownames(data4),ppname)
senti_mat2<-cbind(senti_mat[n1,2],rep("first1",10))
senti_mat2<-rbind( senti_mat2 , cbind(senti_mat[n2,2],rep("first2",10)) )
senti_mat2<-rbind( senti_mat2 , cbind(senti_mat[n3,2],rep("second",10)) )
senti_mat2<-rbind( senti_mat2 , cbind(senti_mat[n4,2],rep("third",10)) )
colnames(senti_mat2)<-c("sentimental_scores","personal_pron")
dat<-data.frame(senti_mat2)
p <- ggplot(dat, aes(personal_pron, as.numeric(sentimental_scores)))
p + geom_boxplot()

According to the plot, First person plural’s “Fan Club” tend to be more negative,while the third person form’s “Fan Club” seem to be more positive. But there is no obvious differences.

4.6 Each personal pronoun’s “Fan Club” feature : average of word using times?

#avg time vs person
avg_mat<-matrix(nrow = nrow(inaug.list),ncol = 2)
avg_mat[,1]<-ppname
for(i in seq(nrow(inaug.list))) {
  test<-matsort[matsort[,"name"]==paste(inaug.list$File[i],inaug.list$Term[i]),]
  avg_mat[i,2]<-sum(as.numeric(test[,3]))/nrow(test)
}
senti_mat3<-cbind(avg_mat[n1,2],rep("first1",10))
senti_mat3<-rbind( senti_mat3 , cbind(avg_mat[n2,2],rep("first2",10)) )
senti_mat3<-rbind( senti_mat3 , cbind(avg_mat[n3,2],rep("second",10)) )
senti_mat3<-rbind( senti_mat3 , cbind(avg_mat[n4,2],rep("third",10)) )
colnames(senti_mat3)<-c("word_avg_time","personal_pron")
dat<-data.frame(senti_mat3)
p <- ggplot(dat, aes(personal_pron, as.numeric(word_avg_time)))
p + geom_boxplot()

According to the plot, First person plural’s “Fan Club” tend to use the same words for less times,the median is about 12 times;while the third person form’s “Fan Club” using the same words for more times,the median is about 27 times.

Part 5 - What are they talking/feeling using personal pronoun ?

In this part,we go a little deeper to each sentences.What’s the weight of personal pronouns used in each sentences? In those sentences,what are they talking about and what emotion are they try to convey,these are what we care in this part.

We mainly make two plots to compare.One of them is stacked bar plot,demonstrating the four proportions of four personal pronouns for each sentence in one speech.The second is an area plot,showing different emotions for each sentence in one speech.

After check the plots for each presidents one by one,I will share three findings here.

Finding 1:first singular form always come with trust and anticipation.

senten_mat2<-melt(senten_mat(2))
sen_dat<-data.frame(sentence.number=senten_mat2$Var1,times=senten_mat2$value,personal_pronoun=senten_mat2$Var2,2)
senti_mat<-round(count_emo(2)[,c(1,2,4,5,7,8)],2)
rownames(senti_mat)<-seq(1,nrow(senti_mat))
senti_mat2<-melt(senti_mat)
senti_dat<-data.frame(sentence_number=senti_mat2$Var1,score=senti_mat2$value,sentiment=senti_mat2$Var2)

#par(mfrow=c(1,2))
a1<-ggplot(sen_dat,aes(sentence.number,times,fill=personal_pronoun))+geom_bar(stat="identity",position="stack")+ggtitle("")+guides(fill=guide_legend(title=NULL))+ scale_fill_brewer(palette = "Blues")+ xlab("sentence number")
#b1<-ggplot(senti_dat, aes(x = sentence_number, y = score, fill = sentiment)) +
#  geom_area() 
# + scale_fill_brewer(palette = "RdBu", breaks = rev(c(factor(sentiment))))
#b1<-ggplot(senti_dat,aes(x = sentence_number, y = score, fill = sentiment))+geom_bar(stat="identity",position="stack")+ggtitle("")+guides(fill=guide_legend(title=NULL))
#grid.arrange(a1,b1,nrow=2)
a1
senten_mat2<-melt(senten_mat(2))
sen_dat<-data.frame(sentence.number=senten_mat2$Var1,times=senten_mat2$value,personal_pronoun=senten_mat2$Var2,2)
senti_mat<-round(count_emo(2)[,c(1,2,4,5,7,8)],2)
rownames(senti_mat)<-seq(1,nrow(senti_mat))
senti_mat2<-melt(senti_mat)
senti_dat<-data.frame(sentence_number=senti_mat2$Var1,score=senti_mat2$value,sentiment=senti_mat2$Var2)
#par(mfrow=c(1,2))
a1<-ggplot(sen_dat,aes(sentence.number,times,fill=personal_pronoun))+geom_bar(stat="identity",position="stack")+ggtitle("")+guides(fill=guide_legend(title=NULL))+ scale_fill_brewer(palette = "Blues")+ xlab("sentence number")
#b1<-ggplot(senti_dat, aes(x = sentence_number, y = score, fill = sentiment)) +
#  geom_area() 
# + scale_fill_brewer(palette = "RdBu", breaks = rev(c(factor(sentiment))))
#b1<-ggplot(senti_dat,aes(x = sentence_number, y = score, fill = sentiment))+geom_bar(stat="identity",position="stack")+ggtitle("")+guides(fill=guide_legend(title=NULL))
#grid.arrange(a1,b1,nrow=2)
a1

eArea(senti_mat)

#find topics
#test<-topic_wc(2,1)
#test<-test[7:65,]
#dat<-data.frame(word=test[,"word"],freq=test[,"n"])
#eWordcloud(dat, namevar = ~word, datavar = ~freq,size = c(600, 600),title = "George Washington & fist person singular",rotationRange = c(-1, 1))

[for the area plot]

x-axis:sentence number

y-axis:the weight of a certain kind of emotion being detected.

senten_mat2<-melt(senten_mat(28))
sen_dat<-data.frame(sentence.number=senten_mat2$Var1,times=senten_mat2$value,personal_pronoun=senten_mat2$Var2,2)
senti_mat<-round(count_emo(28)[,c(1,2,4,5,7,8)],2)
rownames(senti_mat)<-seq(1,nrow(senti_mat))
senti_mat2<-melt(senti_mat)
senti_dat<-data.frame(sentence_number=senti_mat2$Var1,score=senti_mat2$value,sentiment=senti_mat2$Var2)
#par(mfrow=c(1,2))
a1<-ggplot(sen_dat,aes(sentence.number,times,fill=personal_pronoun))+geom_bar(stat="identity",position="stack")+ggtitle("")+guides(fill=guide_legend(title=NULL))+ scale_fill_brewer(palette = "Blues")+ xlab("sentence number")
#b1<-ggplot(senti_dat, aes(x = sentence_number, y = score, fill = sentiment)) +
#  geom_area() 
# + scale_fill_brewer(palette = "RdBu", breaks = rev(c(factor(sentiment))))
#b1<-ggplot(senti_dat,aes(x = sentence_number, y = score, fill = sentiment))+geom_bar(stat="identity",position="stack")+ggtitle("")+guides(fill=guide_legend(title=NULL))
#grid.arrange(a1,b1,nrow=2)
a1

eArea(senti_mat)

#find_sen(28,134)
#find_sen(28,135)
#find_sen(28,136)
#find_sen(28,137)
#test<-topic_wc(28,1)[1:60,]
#test<-test[6:60,]
#dat<-data.frame(word=test[,"word"],freq=test[,"n"])
#eWordcloud(dat, namevar = ~word, datavar = ~freq,size = c(600, 600),title = "WilliamMcKinley & fist person singular",rotationRange = c(-1, 1))

Finding 2 :first plural form always convey positive emotions.

In the following two examples,there is light blue showing use of first person plural form in the first plot,and in the second plot,when we exclude negative emotions we can see the positive fluctuation pattern is one-to-one corresponded with the light blue in plot 1,which suggests first plural form always convey positive emotions.

senten_mat2<-melt(senten_mat(45))
sen_dat<-data.frame(sentence.number=senten_mat2$Var1,times=senten_mat2$value,personal_pronoun=senten_mat2$Var2)

par(mfrow=c(4,1), mar=c(1,0,2,0), bty="n", xaxt="n", yaxt="n", font.main=1)
a2<-ggplot(sen_dat,aes(sentence.number,times,fill=personal_pronoun))+geom_bar(stat="identity",position="stack")+ggtitle("")+guides(fill=guide_legend(title=NULL))+
  scale_fill_brewer(palette = "Blues")+ xlab("sentence number")

senti_mat3<-round(count_emo(45)[,c(1,2,4,5,7,8)],2)
rownames(senti_mat3)<-seq(1,nrow(senti_mat3))
senti_mat4<-melt(senti_mat3)
senti_dat2<-data.frame(sentence_number=senti_mat4$Var1,score=senti_mat4$value,sentiment=senti_mat4$Var2)
#b2<-ggplot(senti_dat2, aes(x = sentence_number, y = score, fill = sentiment)) +
#  geom_area() 
#b2<-ggplot(senti_dat2,aes(x = sentence_number, y = score, fill = sentiment))+geom_bar(stat="identity",position="stack")+ggtitle("")+guides(fill=guide_legend(title=NULL))
a2
senten_mat2<-melt(senten_mat(45))
sen_dat<-data.frame(sentence.number=senten_mat2$Var1,times=senten_mat2$value,personal_pronoun=senten_mat2$Var2)
par(mfrow=c(4,1), mar=c(1,0,2,0), bty="n", xaxt="n", yaxt="n", font.main=1)
a2<-ggplot(sen_dat,aes(sentence.number,times,fill=personal_pronoun))+geom_bar(stat="identity",position="stack")+ggtitle("")+guides(fill=guide_legend(title=NULL))+
  scale_fill_brewer(palette = "Blues")+ xlab("sentence number")
senti_mat3<-round(count_emo(45)[,c(1,2,4,5,7,8)],2)
rownames(senti_mat3)<-seq(1,nrow(senti_mat3))
senti_mat4<-melt(senti_mat3)
senti_dat2<-data.frame(sentence_number=senti_mat4$Var1,score=senti_mat4$value,sentiment=senti_mat4$Var2)
#b2<-ggplot(senti_dat2, aes(x = sentence_number, y = score, fill = sentiment)) +
#  geom_area() 
#b2<-ggplot(senti_dat2,aes(x = sentence_number, y = score, fill = sentiment))+geom_bar(stat="identity",position="stack")+ggtitle("")+guides(fill=guide_legend(title=NULL))
a2

apply(senti_mat3,2,mean)
       anger anticipation         fear          joy     surprise        trust 
  0.01402062   0.03164948   0.03309278   0.03288660   0.01072165   0.05123711 
eArea(senti_mat3)

#test<-topic_wc(45,2)[1:60,]
#dat<-data.frame(word=test[,"word"],freq=test[,"n"])
#eWordcloud(dat, namevar = ~word, datavar = ~freq)

[for the area plot]

x-axis:sentence number

y-axis:the weight of a certain kind of emotion being detected.

senten_mat2<-melt(senten_mat(57))
sen_dat<-data.frame(sentence.number=senten_mat2$Var1,times=senten_mat2$value,personal_pronoun=senten_mat2$Var2,2)
senti_mat<-round(count_emo(57)[,c(1,2,4,5,7,8)],2)
rownames(senti_mat)<-seq(1,nrow(senti_mat))
senti_mat2<-melt(senti_mat)
senti_dat<-data.frame(sentence_number=senti_mat2$Var1,score=senti_mat2$value,sentiment=senti_mat2$Var2)
#par(mfrow=c(1,2))
a1<-ggplot(sen_dat,aes(sentence.number,times,fill=personal_pronoun))+geom_bar(stat="identity",position="stack")+ggtitle("")+guides(fill=guide_legend(title=NULL))+ scale_fill_brewer(palette = "Blues")+ xlab("sentence number")
#b1<-ggplot(senti_dat, aes(x = sentence_number, y = score, fill = sentiment)) +
#  geom_area() 
# + scale_fill_brewer(palette = "RdBu", breaks = rev(c(factor(sentiment))))
#b1<-ggplot(senti_dat,aes(x = sentence_number, y = score, fill = sentiment))+geom_bar(stat="identity",position="stack")+ggtitle("")+guides(fill=guide_legend(title=NULL))
#grid.arrange(a1,b1,nrow=2)
a1

eArea(senti_mat)

#find_sen(28,134)
#find_sen(28,135)
#find_sen(28,136)
#find_sen(28,137)
apply(senti_mat,2,mean)
       anger anticipation         fear          joy     surprise        trust 
  0.01561905   0.03638095   0.02866667   0.03800000   0.01390476   0.04952381 
#test<-topic_wc(35,2)[1:60,]
#dat<-data.frame(word=test[,"word"],freq=test[,"n"])
#eWordcloud(dat, namevar = ~word, datavar = ~freq)

Finding 3 : Anger often begin with third person form.

The third is about anger which is a kind of rare emotion in presidents speech.But once it appear the red part showing anger,the coresponding part is dark blue ,that is sentence with third form.We can see this situation in the following two examples.

senten_mat2<-melt(senten_mat(21))
sen_dat<-data.frame(sentence.number=senten_mat2$Var1,times=senten_mat2$value,personal_pronoun=senten_mat2$Var2)
a3<-ggplot(sen_dat,aes(sentence.number,times,fill=personal_pronoun))+geom_bar(stat="identity",position="stack")+ggtitle("")+guides(fill=guide_legend(title=NULL))+ scale_fill_brewer(palette = "Blues")+ xlab("sentence number")
senti_mat5<-round(count_emo(21)[,c(1,2,4,5,7,8)],2)
rownames(senti_mat5)<-seq(1,nrow(senti_mat5))
senti_mat6<-melt(senti_mat5)
senti_dat3<-data.frame(sentence_number=senti_mat6$Var1,score=senti_mat6$value,sentiment=senti_mat6$Var2)
b3<-ggplot(senti_dat3,aes(x = sentence_number, y = score, fill = sentiment))+geom_bar(stat="identity",position="stack")+ggtitle("")+guides(fill=guide_legend(title=NULL))
#b3<-ggplot(senti_dat3, aes(x = sentence_number, y = score, fill = sentiment)) +
#  geom_area() 
a3

eArea(senti_mat5)

apply(senti_mat5,2,mean,na.rm=T)
       anger anticipation         fear          joy     surprise        trust 
  0.01704082   0.04326531   0.03316327   0.04204082   0.01255102   0.08020408 
#test<-topic_wc(57,2)[1:60,]
#dat<-data.frame(word=test[,"word"],freq=test[,"n"])
#eWordcloud(dat, namevar = ~word, datavar = ~freq)

[for the area plot]

x-axis:sentence number

y-axis:the weight of a certain kind of emotion being detected.

senten_mat2<-melt(senten_mat(43))
sen_dat<-data.frame(sentence.number=senten_mat2$Var1,times=senten_mat2$value,personal_pronoun=senten_mat2$Var2)
a3<-ggplot(sen_dat,aes(sentence.number,times,fill=personal_pronoun))+geom_bar(stat="identity",position="stack")+ggtitle("")+guides(fill=guide_legend(title=NULL))+ scale_fill_brewer(palette = "Blues")+ xlab("sentence number")
senti_mat5<-round(count_emo(43)[,c(1,2,4,5,7,8)],2)
rownames(senti_mat5)<-seq(1,nrow(senti_mat5))
senti_mat6<-melt(senti_mat5)
senti_dat3<-data.frame(sentence_number=senti_mat6$Var1,score=senti_mat6$value,sentiment=senti_mat6$Var2)
b3<-ggplot(senti_dat3,aes(x = sentence_number, y = score, fill = sentiment))+geom_bar(stat="identity",position="stack")+ggtitle("")+guides(fill=guide_legend(title=NULL))
#b3<-ggplot(senti_dat3, aes(x = sentence_number, y = score, fill = sentiment)) +
#  geom_area() 
a3

eArea(senti_mat5)

apply(senti_mat5,2,mean,na.rm=T)
       anger anticipation         fear          joy     surprise        trust 
  0.01704082   0.04326531   0.03316327   0.04204082   0.01255102   0.08020408 
#test<-topic_wc(57,2)[1:60,]
#dat<-data.frame(word=test[,"word"],freq=test[,"n"])
#eWordcloud(dat, namevar = ~word, datavar = ~freq)

Part 6 - Next step

LS0tCm91dHB1dDoKICBodG1sX25vdGVib29rOiBkZWZhdWx0CiAgaHRtbF9kb2N1bWVudDogZGVmYXVsdAogIHBkZl9kb2N1bWVudDogZGVmYXVsdAotLS0KPGRpdiBpZD0iaGVhZGVyIj4KPGgxIGNsYXNzPSJ0aXRsZSI+PGI+PGZvbnQgZmFjZT0iVGltZXMgTmV3IFJvbWFuIj5UaGUgdXNlIG9mIHBlcnNvbmFsIHByb25vdW4gaW4gSW5hdWd1cmFsIFNwZWVjaGVzPC9mb250PjwvYj48L2gxPgo8aDQgY2xhc3M9ImF1dGhvciI+PGVtPjxmb250IGZhY2U9IlRpbWVzIE5ldyBSb21hbiI+WWl0b25nIEh1PC9mb250PjwvZW0+PC9oND4KPGg0IGNsYXNzPSJkYXRlIj48ZW0+PGZvbnQgZmFjZT0iVGltZXMgTmV3IFJvbWFuIj5GZWJydWFyeSAzcmQuIDIwMTc8L2ZvbnQ+PC9lbT48L2g0Pgo8L2Rpdj4KPGRpdiBzdHlsZT0idGV4dC1hbGlnbjpjZW50ZXIiPiFbaW1hZ2VdKC4uL2ZpZ3MvcGVyc29uYWxwcm8uanBlZyk8L2Rpdj4KCjxoMz48Zm9udCBmYWNlPSJUaW1lcyBOZXcgUm9tYW4iPlBhcnQgMCAtIFRvcGljIGludHJvZHVjdGlvbjwvZm9udD48L2gzPgo8cD5QZW9wbGUgYWx3YXlzIHVzZSBhIGxvdCBvZiBwZXJzb25hbCBwcm9ub3VucyB0byBhdm9pZCByZXBlYXRpbmcgc29tZW9uZeKAmXMgbmFtZXMgdGltZSBhbmQgdGltZSBhZ2Fpbi4gRGlmZmVyZW50IHBlb3BsZSBtYXkgdXNlIGRpZmZlcmVudCBwZXJzb25hbCBwcm9ub3VucyBmb3IgZGlmZmVyZW50IHdlaWdodCBpbiBkaWZmZXJlbnQgc2l0dWF0aW9uIHRvIGRlbW9uc3RyYXRlIGRpZmZlcmVudCBtZWFuaW5ncyBhbmQgZW1vdGlvbnMuIFdoYXQgYWJvdXQgdGhlIHNpdHVhdGlvbnMgaW4gcHJlc2lkZW50cycgSW5hdWd1cmFsIFNwZWVjaGVzPzwvcD4KCgo8aDM+PGZvbnQgZmFjZT0iVGltZXMgTmV3IFJvbWFuIj5QYXJ0IDEgLSBQYWNrYWdlcyBwcmVwYXJhaW9uPC9mb250PjwvaDM+CgpgYGB7cixtZXNzYWdlPUYsd2FybmluZz1GfQpwYWNrYWdlcy51c2VkPWMoIlJDb2xvckJyZXdlciIsInFkYXAiLCJnZ3Bsb3QyIiwicmVzaGFwZTIiLCJzeXV6aGV0IiwidG0iLCJxZGFwIiwicmVzaGFwZTIiLCJncmlkRXh0cmEiLCJnZ3Bsb3QyIiwid29yZGNsb3VkIiwiZHBseXIiLCJ0aWR5dGV4dCIpCgojIGNoZWNrIHBhY2thZ2VzIHRoYXQgbmVlZCB0byBiZSBpbnN0YWxsZWQuCnBhY2thZ2VzLm5lZWRlZD1zZXRkaWZmKHBhY2thZ2VzLnVzZWQsIAogICAgICAgICAgICAgICAgICAgICAgICBpbnRlcnNlY3QoaW5zdGFsbGVkLnBhY2thZ2VzKClbLDFdLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2thZ2VzLnVzZWQpKQojIGluc3RhbGwgYWRkaXRpb25hbCBwYWNrYWdlcwppZihsZW5ndGgocGFja2FnZXMubmVlZGVkKT4wKXsKICBpbnN0YWxsLnBhY2thZ2VzKHBhY2thZ2VzLm5lZWRlZCwgZGVwZW5kZW5jaWVzID0gVFJVRSkKfQpyZXF1aXJlKGRldnRvb2xzLHF1aWV0bHkgPSBUKQppbnN0YWxsX2dpdGh1YigncmVjaGFydHMnLCAndGFpeXVuJykKCiMgbGlicmFyeSBwYWNrYWdlcwpsaWJyYXJ5KCJSQ29sb3JCcmV3ZXIiLHF1aWV0bHkgPSBUKQpsaWJyYXJ5KCJxZGFwIixxdWlldGx5ID0gVCkKbGlicmFyeSgiZ2dwbG90MiIscXVpZXRseSA9IFQpCmxpYnJhcnkoInJlc2hhcGUyIixxdWlldGx5ID0gVCkKbGlicmFyeSgic3l1emhldCIscXVpZXRseSA9IFQpCmxpYnJhcnkoInRtIixxdWlldGx5ID0gVCkKbGlicmFyeSgicWRhcCIscXVpZXRseSA9IFQpCmxpYnJhcnkoInJlc2hhcGUyIixxdWlldGx5ID0gVCkKbGlicmFyeSgiZ3JpZEV4dHJhIixxdWlldGx5ID0gVCkKbGlicmFyeSgiZ2dwbG90MiIscXVpZXRseSA9IFQpCmxpYnJhcnkoIndvcmRjbG91ZCIscXVpZXRseSA9IFQpCmxpYnJhcnkoImRwbHlyIixxdWlldGx5ID0gVCkKbGlicmFyeSgidGlkeXRleHQiLHF1aWV0bHkgPSBUKQpsaWJyYXJ5KCJyZWNoYXJ0cyIscXVpZXRseSA9IFQpCgojcGFydCBvZiBjb2RlcyBhcmUgaW4gdGhpcyBSIGZpbGUuCnNvdXJjZSgiLi4vbGliL2N1c3RvbWl6ZWRfZnVuY3Rpb24uUiIpCmBgYAoKCjxoMz48Zm9udCBmYWNlPSJUaW1lcyBOZXcgUm9tYW4iPlBhcnQgMiAtIERhdGEgY2xlYW5pbmc8L2ZvbnQ+PC9oMz4KCjxwPldlIGNvdW50IHRoZSB3b3JkIGZyZXF1ZW5jeSBmb3IgZWFjaCBzcGVlY2hlcyBhbmQgbWFrZSB0aGlzIGRhdGEgbWF0cml4IG9uIHdoaWNoIG91ciB3aG9sZSBhbmFseXNpcyB3b3VsZCBiYXNlZC48L3A+CgpgYGB7cix3YXJuaW5nPUZ9CmluYXVnLmxpc3Q9cmVhZC5jc3YoIi4uL2RhdGEvSW5hdWd1cmF0aW9uSW5mby5jc3YiLCBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UpCmluYXVnLmRhdGE9cmVhZC50YWJsZSgiLi4vZGF0YS9JbmF1Z3VhdGlvbkRhdGVzLnR4dCIsIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRSxibGFuay5saW5lcy5za2lwPUYsc2VwPSAiXHQiKQptYXQxPC1OVUxMCgpmb3IoaSBpbiBzZXEobnJvdyhpbmF1Zy5saXN0KSkpIHsKZmlsZW5hbWUgPC0gcGFzdGUwKCIuLi9kYXRhL0luYXVndXJhbFNwZWVjaGVzL2luYXVnIiwgCiAgICAgICAgICAgICAgICAgICAgIGluYXVnLmxpc3QkRmlsZVtpXSwgIi0iLCAKICAgICAgICAgICAgICAgICAgICAgaW5hdWcubGlzdCRUZXJtW2ldLCAiLnR4dCIpCnR4IDwtIHJlYWRMaW5lcyhmaWxlbmFtZSx3YXJuPUYpCmlmIChpPT01OCkgCnsKICB0eDwtcGFzdGUodHgsIGNvbGxhcHNlID0gIiAiKQogIHR4X3dvcmRzIDwtIHN0cnNwbGl0KHR4LCBzcGxpdCA9ICIgIilbWzFdXQp9CmVsc2UKdHhfd29yZHMgPC0gc3Ryc3BsaXQodHgsIHNwbGl0ID0gIiAiKVtbMV1dCmRhdGVfcGF0dGVybjIgPC0gIlthLXpBLXpdKyIKdHhfd29yZHMyIDwtIGdyZXAodHhfd29yZHMsIHBhdHRlcm4gPSBkYXRlX3BhdHRlcm4yLCB2YWx1ZT1UKQp0eF9sb2cgPC0gZ3JlcGwodHhfd29yZHMyLCBwYXR0ZXJuID0gZGF0ZV9wYXR0ZXJuMikKbWF0Y2hlcyA8LSBncmVnZXhwcihwYXR0ZXJuID0gZGF0ZV9wYXR0ZXJuMiwgdGV4dCA9IHR4X3dvcmRzMlt0eF9sb2ddKQp0eF93b3JkcyA8LSB1bmxpc3QocmVnbWF0Y2hlcyh0eF93b3JkczJbdHhfbG9nXSwgbWF0Y2hlcykpCnR4X3dvcmRzIDwtIHVubGlzdChybV9zdG9wd29yZHModHhfd29yZHMpKQptYXQ8LU5VTEwKdGFibGU8LXRhYmxlKHR4X3dvcmRzKQp3b3JkPC1uYW1lcyh0YWJsZSkKbjwtdW5uYW1lKHRhYmxlKQptYXRuYW1lPC1wYXN0ZShpbmF1Zy5saXN0JEZpbGVbaV0saW5hdWcubGlzdCRUZXJtW2ldKQptYXQ8LWNiaW5kKHJlcChtYXRuYW1lLG5yb3cobikpLHdvcmQsbikKbWF0MTwtcmJpbmQobWF0MSxtYXQpCn0KY29sbmFtZXMobWF0MSk8LWMoIm5hbWUiLCJ3b3JkIiwibiIpIAptYXRzb3J0PC1tYXQxW29yZGVyKGFzLm51bWVyaWMobWF0MVssM10pLGRlY3JlYXNpbmcgPSBUKSxdCmhlYWQobWF0c29ydCkKYGBgCgo8aDM+PGZvbnQgZmFjZT0iVGltZXMgTmV3IFJvbWFuIj5QYXJ0IDMgLSBEaWZmZXJlbnQgcHJlc2lkZW50IHVzZXMgcGVyc29uYWwgcHJvbm91biBmb3IgZGlmZmVyZW50IHdlaWdodDwvZm9udD48L2gzPgoKPHA+SW4gdGhpcyBwYXJ0LHdlIHdpbGwgZG8gYSBnZW5lcmFsIGFuYWx5c2lzLHRvIHNlZSB0aGUgZ2VuZXJhbCB0cmVuZCBhbmQgZmluZCBkaWZmZXJlbmNlIG9mIHRoZSB3ZWlnaHQgd2hlbiBkaXZpZGVkIGJ5IGRpZmZlcmVudCBmYWN0b3JzLkJ5IHNheWluZyB3ZWlnaHQsd2UgbWVhbiB0aGUgdGltZXMgb25lIHVzaW5nIGEgY2VydGFpbiBwZXJzb25hbCBwcm9ub3VuIGRpdmlkZWQgYnkgdGhlIHRvdGFsIHRpbWVzIGhlIHVzaW5nIGFsbCBmb3VyIHR5cGVzIG9mIHByb25vdW5zLjwvcD4KPHA+V2UgZGl2aWRlIHBlcnNvbmFsIHByb25vdW5zIGludG8gNCB0eXBlcyxmaXJzdCBwZXJzb24gc2luZ3VsYXIgZm9ybSxmaXJzdCBwZXJzb24gcGx1cmFsIGZvcm0sc2Vjb25kIHBlcnNvbiBmb3JtIGFuZCB0aGlyZCBwZXJzb24gZm9ybS48L3A+CgoKPGRpdiBzdHlsZT0idGV4dC1hbGlnbjpjZW50ZXIiPiFbaW1hZ2VdKC4uL2ZpZ3MvcGVyc29uYWx0eXBlLmpwZWcpPC9kaXY+CgpgYGB7cix3YXJuaW5nPUZ9CiNwZXJzb25hbCBwcm9ub3VuCgpmaXJzdDE8LWMoIkkiLCJtZSIsIm1pbmUiLCJteSIpCmZpcnN0MjwtYygid2UiLCJvdXIiLCJvdXJzIiwidXMiKQpzZWNvbmQ8LWMoInlvdSIsInlvdXIiLCJ5b3VycyIpCnRoaXJkPC1jKCJoZSIsInNoZSIsIml0IiwiaGltIiwiaGVyIiwiaGlzIiwiaGVycyIsInRoZXkiLCJ0aGVtIiwidGhlaXIiKQpwZXJzb25hbDwtbGlzdChmaXJzdDEsZmlyc3QyLHNlY29uZCx0aGlyZCkKCnBwX21hdDwtbWF0cml4KG5yb3cgPSBucm93KGluYXVnLmxpc3QpLG5jb2wgPSA0KQpmb3IoaSBpbiBzZXEobnJvdyhpbmF1Zy5saXN0KSkpIHsKICB0ZXN0PC1tYXRzb3J0W21hdHNvcnRbLCJuYW1lIl09PXBhc3RlKGluYXVnLmxpc3QkRmlsZVtpXSxpbmF1Zy5saXN0JFRlcm1baV0pLCJ3b3JkIl0KICBwcF9tYXRbaSxdPC1maW5kX3BlcnNvbmFsX3Byb25vdW4odGVzdCkKfQpwcG5hbWU8LU5VTEwKZm9yKGkgaW4gc2VxKG5yb3coaW5hdWcubGlzdCkpKSB7CnBwbmFtZVtpXSA8LSBwYXN0ZShpbmF1Zy5saXN0JEZpbGVbaV0sIGluYXVnLmxpc3QkVGVybVtpXSkgfQpyb3duYW1lcyhwcF9tYXQpPC1wcG5hbWUKY29sbmFtZXMocHBfbWF0KTwtYygiZmlyc3QxIiwiZmlyc3QyIiwic2Vjb25kIiwidGhpcmQiKQpoZWFkKHBwX21hdCkKYGBgCgpgYGB7cn0KcHBfbWF0MTwtcHBfbWF0CnJvd25hbWVzKHBwX21hdDEpPC1zZXEoMTc4OSwyMDE3LDQpCnBwX21hdDI8LW1lbHQocHBfbWF0MSkKcHBfbWF0MzwtbWVsdChwcF9tYXQpCgpuZXcxPC1tYXQybWF0KHBwX21hdCkKYTwtZ2dwbG90KGRhdGEuZnJhbWUocGVyc29uYWxfcHJvbm91bj1uZXcxWywidHlwZSJdLG5ldzFbLCJuYW1lIl0sbmV3MVssInByb3AiXSksIGFlcyh4PWZhY3RvcihuZXcxWywibmFtZSJdLCBsZXZlbHM9dW5pcXVlKG5ldzFbLCJuYW1lIl0pKSx5PW5ldzFbLCJwcm9wIl0sIGNvbG91cj1wZXJzb25hbF9wcm9ub3VuLGdyb3VwPXBlcnNvbmFsX3Byb25vdW4pKSsgZ2VvbV9saW5lKHNpemU9MikgKyB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfYmxhbmsoKSkgKyB4bGFiKCJ0aW1lIHdpdGggZGlmZmVyZW50IHByZXNpZGVudHMiKSArIHlsYWIoInByb3BvcnRpb24iKSAKCnBwX2RhdDwtZGF0YS5mcmFtZSh5ZWFyPXBwX21hdDIkVmFyMSxwcm9wb3J0aW9uPXBwX21hdDIkdmFsdWUscGVyc29uYWxfcHJvbm91bj1wcF9tYXQyJFZhcjIpCmI8LWdncGxvdChwcF9kYXQsIGFlcyh4ID0geWVhciwgeSA9IHByb3BvcnRpb24sIGZpbGwgPSBwZXJzb25hbF9wcm9ub3VuKSkgKwogIGdlb21fYXJlYSgpICsKICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIkJsdWVzIiwgYnJlYWtzID0gcmV2KGMoInRoaXJkIiwic2Vjb25kIiwiZmlyc3QyIiwiZmlyc3QxIikpKQoKcHBfZGF0PC1kYXRhLmZyYW1lKHByZXNpZGVudD1wcF9tYXQzJFZhcjEscHJvcG9ydGlvbj1wcF9tYXQyJHZhbHVlLHBlcnNvbmFsX3Byb25vdW49cHBfbWF0MiRWYXIyKQpjPC1nZ3Bsb3QocHBfZGF0LGFlcyhwcmVzaWRlbnQscHJvcG9ydGlvbixmaWxsPXBlcnNvbmFsX3Byb25vdW4pKStnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIscG9zaXRpb249InN0YWNrIikrZ2d0aXRsZSgiIikrZ3VpZGVzKGZpbGw9Z3VpZGVfbGVnZW5kKHRpdGxlPU5VTEwpKSsKICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIkJsdWVzIikrIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF9ibGFuaygpKSArIHhsYWIoInRpbWUgd2l0aCBkaWZmZXJlbnQgcHJlc2lkZW50cyIpCiNncmlkLmFycmFuZ2UoYixjLG5yb3c9MikKYGBgCgo8cD5Ob3RpY2U6VGhlIHBsb3QoYW5kIHNvbWUgZm9sbG93aW5nIHBsb3RzKSBhcmUgaW50ZXJhY3RpdmUgYnkgbW92aW5nIHlvdXIgbW91c2UgdG8gYSBjZXJ0YWluIGRhdGEgcG9pbnQsZGV0YWlscyBjYW4gYmUgc2hvd24uPC9wPgoKPGg0PjMuMSBHZW5lcmFsIFRyZW5kPC9oND4KCngtYXhpczp0aW1lIChkaWZmZXJlbnQgcHJlc2lkZW50cykKeS1heGlzOnRoZSB3ZWlnaHQgb2YgYSBjZXJ0YWluIGtpbmQgb2YgcGVyc29uYWwgcHJvbm91biBiZWluZyB1c2VkLgoKYGBge3J9CmVBcmVhKHBwX21hdDEpCmBgYAo8cD5JbiBnZW5lcmFsPC9wPgorIFRoZXJlIGlzIG5vIG9idmlvdXMgdHJlbmQsanVzdCBzb21lIGZsdWN0dWF0aW9ucyBmb3Igc2Vjb25kICYgdGhpcmQgcGVyc29uIHVzaW5nIHdlaWdodC4KKyBUaGVyZSBpcyBhIHNsaWdodGx5IGRlY3JlYXNpbmcgZm9yIGZpcnN0IHBlcnNvbiBzaW5ndWxhciBmb3JtIHVzaW5nIHdlaWdodC4KKyBUaGVyZSBpcyBhIHNsaWdodGx5IGluY3JlYXNpbmcgZm9yIGZpcnN0IHBlcnNvbiBwbHVyYWwgZm9ybSB1c2luZyB3ZWlnaHQuCgo8cD5JdCdzIHF1aXRlIHJlYXNvbmFibGUsc2luY2UgcHJlc2lkZW50cyBjb21lIHRvIHJlYWxpemUgdGhhdCB0aGV5IHNob3VsZCBlbXBoYXNpemUgcGVvcGxlJ3MgcmlnaHRzIGFuZCByZXNwb25zaWJpbGl0aWVzIHRvIGxldCBwZW9wbGUgZmVlbCB0aGF0IHRoZXkgYXJlIGJlaW5nIHRvZ2V0aGVyLHRoZSBpbnRlcmVzdHMgb2YgZXZlcnkgY2l0aXplbnMgYXJlIGNsb3NlbHkgcmVsYXRlZCB0byBkZXN0aW55IG9mIHRoZSBVbml0ZWQgU3RhdGVzLHJhdGhlciB0aGFuIGp1c3QgdGFsa2luZyBhYm91dCB0aGVtc2VsdmVzLjwvcD4KCgo8aDQ+My4yIENvbXBhcmluZyBiZXR3ZWVuIGRpZmZlcmVudCB0ZXJtczwvaDQ+CgoKYGBge3Isd2FybmluZz1GfQojZGlmZmVyZW50IHRlcm0gCmF2ZzwtYXBwbHkocHBfbWF0LDIsbWVhbikKbGlzdDwtdGVybV9zZXAoKQphdmdfdGVybTE8LWFwcGx5KHBwX21hdFtsaXN0W1sxXV0sXSwyLG1lYW4pCmF2Z190ZXJtMjwtYXBwbHkocHBfbWF0W2xpc3RbWzJdXSxdLDIsbWVhbikKZGYxPC1kYXRhLmZyYW1lKGF2ZyxhdmdfdGVybTEsYXZnX3Rlcm0yKQpkYXQ8LXQoZGYxKQpteWRhdDwtbWVsdChkYXQpCiNteWRhdApteWRhdDwtZGF0YS5mcmFtZSh0ZXJtID0gbXlkYXQkVmFyMSxwZXJzb25hbF9wcm9ub3VuID0gbXlkYXQkVmFyMixwcm9wb3J0aW9uPXJvdW5kKG15ZGF0JHZhbHVlLDIpKQpnZ3Bsb3QobXlkYXQsYWVzKHRlcm0scHJvcG9ydGlvbixmaWxsPXBlcnNvbmFsX3Byb25vdW4pKStnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIscG9zaXRpb249InN0YWNrIikrZ2d0aXRsZSgiIikrdGhlbWUoYXhpcy50aWNrcy5sZW5ndGg9dW5pdCgwLjUsJ2NtJykpK2d1aWRlcyhmaWxsPWd1aWRlX2xlZ2VuZCh0aXRsZT1OVUxMKSkrCiAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJCbHVlcyIpCmVSYWRhcih4dGFicyggcHJvcG9ydGlvbn4gdGVybStwZXJzb25hbF9wcm9ub3VuLCBteWRhdCkpCmBgYAo8cD5Gcm9tIHByZXNpZGVudCdzIHRlcm0gMSB0byB0ZXJtIDIsdGhleSB0ZW5kIHRvIHVzZSBtb3JlIGZpcnN0IHBlcnNvbiBwbHVyYWwgZm9ybSB0aGFuIGZpcnN0IHBlcnNvbiBzaW5ndWxhciBmb3JtLkl0J3MgYWxzbyByZWFzb25hYmxlLCBzaW5jZSB0aGUgcHJlc2lkZW50IGFuZCB0aGUgcHVibGljIGJlY29tZSBmYW1pbGlhciB0byBlYWNoIG90aGVyLHNvIHRoZSBwcmVzaWRlbnQgbmF0dXJhbGx5IHRha2UgaGltc2VsZiBhbmQgdGhlIHB1YmxpYyBhcyBhIHdob2xlIGdyb3VwLjwvcD4KCgo8aDQ+My4zIENvbXBhcmluZyBhbW9uZyBkaWZmZXJlbnQgcGFydGllczwvaDQ+CgoKYGBge3Isd2FybmluZz1GfQojZGlmZmVyZW50IHBhcnR5Cm5ld19pbmF1Zy5saXN0PC1jYmluZChpbmF1Zy5saXN0LHBwX21hdCkKZmlyc3QxPC10YXBwbHkobmV3X2luYXVnLmxpc3QkZmlyc3QxLG5ld19pbmF1Zy5saXN0JFBhcnR5LG1lYW4pCmZpcnN0MjwtdGFwcGx5KG5ld19pbmF1Zy5saXN0JGZpcnN0MixuZXdfaW5hdWcubGlzdCRQYXJ0eSxtZWFuKQpzZWNvbmQ8LXRhcHBseShuZXdfaW5hdWcubGlzdCRzZWNvbmQsbmV3X2luYXVnLmxpc3QkUGFydHksbWVhbikKdGhpcmQ8LXRhcHBseShuZXdfaW5hdWcubGlzdCR0aGlyZCxuZXdfaW5hdWcubGlzdCRQYXJ0eSxtZWFuKQojaGVhZChuZXdfaW5hdWcubGlzdCkKI2FnZ3JlZ2F0ZShuZXdfaW5hdWcubGlzdCwpCmRhdDwtcmJpbmQodW5uYW1lKGZpcnN0MSksdW5uYW1lKGZpcnN0MiksdW5uYW1lKHNlY29uZCksdW5uYW1lKHRoaXJkKSkKY29sbmFtZXMoZGF0KTwtbmFtZXMoZmlyc3QxKQpyb3duYW1lcyhkYXQpPC1jKCJmaXJzdDEiLCJmaXJzdDIiLCJzZWNvbmQiLCJ0aGlyZCIpCm15ZGF0PC1tZWx0KGRhdCkKbXlkYXQ8LWRhdGEuZnJhbWUocGVyc29uYWxfcHJvbm91biA9IG15ZGF0JFZhcjEsIHBhcnR5ID0gbXlkYXQkVmFyMixwcm9wb3J0aW9uPXJvdW5kKG15ZGF0JHZhbHVlLDIpKQpnZ3Bsb3QobXlkYXQsYWVzKHBhcnR5LHByb3BvcnRpb24sZmlsbD1wZXJzb25hbF9wcm9ub3VuKSkrZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiLHBvc2l0aW9uPSJzdGFjayIpK2dndGl0bGUoIiIpK3RoZW1lKGF4aXMudGlja3MubGVuZ3RoPXVuaXQoMC41LCdjbScpKStndWlkZXMoZmlsbD1ndWlkZV9sZWdlbmQodGl0bGU9TlVMTCkpKwogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiQmx1ZXMiKSsgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAxNSwgaGp1c3QgPSAwLjUsIHZqdXN0ID0gMC41KSkKZVJhZGFyKHh0YWJzKCBwcm9wb3J0aW9ufiBwYXJ0eStwZXJzb25hbF9wcm9ub3VuLCBteWRhdCkpCmBgYAo8cD5BcyB0aGUgcGxvdCBzaG93bixXaGlnIHVzZWQgZmlyc3QgcGVyc29uIHNpbmd1bGFyIGZvcm0gYW5kIHRoaXJkIHBlcnNvbiBtb3N0IGZyZXF1ZW50bHksdXNlZCBmaXJzdCBwZXJzb24gcGx1cmFsIGZvcm0gYXMgd2VsbCBhcyBzZWNvbmQgcGVyc29uIGF0IGxlYXN0IGZyZXF1ZW5jeS5XaGlsZSBmZWRlcmFsaXN0IGlzIGFsbW9zdCB0aGUgb3Bwb3NpdGUuPC9wPgoKCjxoMz48Zm9udCBmYWNlPSJUaW1lcyBOZXcgUm9tYW4iPlBhcnQgNCAtIEFuYWx5c2lzIG9uIGVhY2gga2luZCBvZiBwZXJzb25hbCBwcm9ub3VuJ3MgQ1JBWlkgRkFOPC9mb250PjwvaDM+Cgo8cD5JbiB0aGlzIHBhcnQsIHdlIHN3aXRjaCBvdXIgYW5hbHlzaXMgZnJvbSB0aGUgb3ZlcmFsbCBkYXRhIHRvIHNvbWUgZXh0cmVtZSBwb2ludHMsIHRvIGFuYWx5c2lzIHRoZSBmZWF0dXJlcyBhYm91dCB0aG9zZSBwcmVzaWRlbnRzIHdobyB1c2UgYSBjZXJ0YWluIHR5cGUgb2YgcGVyc29uYWwgcHJvbm91biBhdCBhIGhpZ2ggZnJlcXVlbmN5LGxpa2UgdG9wIDEwLjwvcD4KYGBge3Isd2FybmluZz1GfQpkYXRhMTwtcHBfbWF0W29yZGVyKHBwX21hdFssMV0sZGVjcmVhc2luZyA9IFQpLF1bMToxMCxdCmRhdGEyPC1wcF9tYXRbb3JkZXIocHBfbWF0WywyXSxkZWNyZWFzaW5nID0gVCksXVsxOjEwLF0KZGF0YTM8LXBwX21hdFtvcmRlcihwcF9tYXRbLDNdLGRlY3JlYXNpbmcgPSBUKSxdWzE6MTAsXQpkYXRhNDwtcHBfbWF0W29yZGVyKHBwX21hdFssNF0sZGVjcmVhc2luZyA9IFQpLF1bMToxMCxdCm5ldzE8LW1hdDJtYXQoZGF0YTEpCm5ldzI8LW1hdDJtYXQoZGF0YTIpCm5ldzM8LW1hdDJtYXQoZGF0YTMpCm5ldzQ8LW1hdDJtYXQoZGF0YTQpCm5ldzE8LWRhdGEuZnJhbWUodHlwZT1uZXcxWywidHlwZSJdLG5hbWU9bmV3MVssIm5hbWUiXSxwcm9wb3J0aW9uPWFzLm51bWVyaWMobmV3MVssInByb3AiXSkpCm5ldzI8LWRhdGEuZnJhbWUodHlwZT1uZXcyWywidHlwZSJdLG5hbWU9bmV3MlssIm5hbWUiXSxwcm9wb3J0aW9uPWFzLm51bWVyaWMobmV3MlssInByb3AiXSkpCm5ldzM8LWRhdGEuZnJhbWUodHlwZT1uZXczWywidHlwZSJdLG5hbWU9bmV3M1ssIm5hbWUiXSxwcm9wb3J0aW9uPWFzLm51bWVyaWMobmV3M1ssInByb3AiXSkpCm5ldzQ8LWRhdGEuZnJhbWUodHlwZT1uZXc0WywidHlwZSJdLG5hbWU9bmV3NFssIm5hbWUiXSxwcm9wb3J0aW9uPWFzLm51bWVyaWMobmV3NFssInByb3AiXSkpCmluYXVnLmxpc3Q9cmVhZC5jc3YoIi4uL2RhdGEvSW5hdWd1cmF0aW9uSW5mby5jc3YiLCBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UpCmluYXVnLmRhdGE9cmVhZC50YWJsZSgiLi4vZGF0YS9JbmF1Z3VhdGlvbkRhdGVzLnR4dCIsIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRSxibGFuay5saW5lcy5za2lwPUYsc2VwPSAiXHQiKQpmaXJzdDE8LWMoIkkiLCJtZSIsIm1pbmUiLCJteSIpCmZpcnN0MjwtYygid2UiLCJvdXIiLCJvdXJzIiwidXMiKQpzZWNvbmQ8LWMoInlvdSIsInlvdXIiLCJ5b3VycyIpCnRoaXJkPC1jKCJoZSIsInNoZSIsIml0IiwiaGltIiwiaGVyIiwiaGlzIiwiaGVycyIsInRoZXkiLCJ0aGVtIiwidGhlaXIiKQpwZXJzb25hbDwtbGlzdChmaXJzdDEsZmlyc3QyLHNlY29uZCx0aGlyZCkKc3BlZWNoLmxpc3Q9cmVhZC5jc3YoIi4uL2RhdGEvSW5hdWd1cmF0aW9uSW5mby5jc3YiLCBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UpCnNwZWVjaC5saXN0JHR5cGU9YyhyZXAoImluYXVnIiwgbnJvdyhzcGVlY2gubGlzdCkpKQpzcGVlY2gubGlzdCRmdWxsdGV4dD1OQQpzZW50ZW5jZS5saXN0PU5VTEwKYGBgCgoKPGg0PjQuMSBUb3AgdGVuIHVzaW5nIGZpcnN0IHBlcnNvbiBzaW5ndWxhciBmb3JtPC9oND4KCisgeC1heGlzOmRpZmZlcmVudCBwcmVzaWRlbnRzCisgeS1heGlzOnRoZSB3ZWlnaHQgb2YgYSBjZXJ0YWluIGtpbmQgb2YgcGVyc29uYWwgcHJvbm91biBiZWluZyB1c2VkLgoKYGBge3J9CmVCYXIobmV3MSwgfm5hbWUsIH5wcm9wb3J0aW9uLCB+dHlwZSkKYGBgCgpgYGB7cn0KdGVzdDwtdG9waWNfd2MoMiwxKQpkYXQ8LWRhdGEuZnJhbWUod29yZD10ZXN0Wywid29yZCJdLGZyZXE9NSphcy5udW1lcmljKHRlc3RbLCJuIl0pKQojcGFyKG1mcm93PWMoMSwyKSkKZVdvcmRjbG91ZChkYXRbNzo2NSxdLCBuYW1ldmFyID0gfndvcmQsIGRhdGF2YXIgPSB+ZnJlcSxzaXplID0gYyg2MDAsIDYwMCksdGl0bGUgPSAiR2VvcmdlIFdhc2hpbmd0b24gJiBmaXJzdCBwZXJzb24gc2luZ3VsYXIiLHJvdGF0aW9uUmFuZ2UgPSBjKC0xLCAxKSkKdGVzdDwtdG9waWNfd2MoMiwzKQpkYXQ8LWRhdGEuZnJhbWUod29yZD10ZXN0Wywid29yZCJdLGZyZXE9NSphcy5udW1lcmljKHRlc3RbLCJuIl0pKQplV29yZGNsb3VkKGRhdFsyOjMyLF0sIG5hbWV2YXIgPSB+d29yZCwgZGF0YXZhciA9IH5mcmVxLHNpemUgPSBjKDYwMCwgNjAwKSx0aXRsZSA9ICJHZW9yZ2UgV2FzaGluZ3RvbiAmIHNlY29uZCBwZXJzb24iLHJvdGF0aW9uUmFuZ2UgPSBjKC0xLCAxKSkKYGBgCjxwPk5vLjEgImZpcnN0IHBlcnNvbiBzaW5ndWxhciB1c2VyIiBpcyBHZW9yZ2UgV2FzaGluZ3Rvbih0ZXJtIDIpLlRoZSA2NyUgcGVyc29uYWwgcHJvbm91biBHZW9yZ2UgV2FzaGluZ3RvbiB1c2VkIGluIGhpcyBzZWNvbmQgcGVyc29uIGlzIGZpcnN0IHBlcnNvbiBzaW5ndWxhciBmb3JtLiBIZSBhbHNvIHVzZWQgc2Vjb25kIHBlcnNvbiBxdWl0ZSBmcmVxdWVudGx5IGF0IGFib3V0IDMzJS4gQWxvbmcgd2l0aCB0aGUgd29yZCBjbG91ZCx3ZSBjYW4gc3BlY3VsYXRlIGluIGhpcyBzcGVlY2hlcyxubyBtYXR0ZXIgdXNpbmcgZmlyc3Qgc2luZ3VsYXIgZm9ybSBvciBzZWNvbmQgZm9ybSxoZSB1c2VkIHdvcmRzIGxpa2UgImFkbWluaXN0cmF0aW9uIiwiY2hpZWYiLGl0IHdhcyBzaG93biB0aGF0IGhlIHRvb2sgaGltc2VsZiBhcyBhIGxlYWRlciBhbmQgd2FudGVkIHRvIGV4cHJlc3MgaGlzIHBvd2VyIHRvIHB1YmxpYy48L3A+CgpgYGB7cn0KdGVzdDwtbWF0c29ydFttYXRzb3J0WywibmFtZSJdID09ICJXaWxsaWFtTWNLaW5sZXkgMSIsXQp0ZXN0MTwtbWF0c29ydFttYXRzb3J0WywibmFtZSJdID09ICJXb29kcm93V2lsc29uIDIiLF0KdGVzdDI8LW1hdHNvcnRbbWF0c29ydFssIm5hbWUiXSA9PSAiSmFtZXNCdWNoYW5hbiAxIixdCnRlc3Q8LXJiaW5kKHRlc3QsdGVzdDEsdGVzdDIpCnRlc3Q8LXRlc3Rbb3JkZXIoYXMubnVtZXJpYyh0ZXN0WywzXSksZGVjcmVhc2luZyA9IFQpLF0KdGVzdDwtdGVzdFsxNzoyNTI5LF0KZGF0PC1kYXRhLmZyYW1lKHdvcmQ9dGVzdFssIndvcmQiXSxmcmVxPXRlc3RbLCJuIl0pCiNwYXIobWZyb3c9YygxLDIpKQplV29yZGNsb3VkKGRhdCwgbmFtZXZhciA9IH53b3JkLCBkYXRhdmFyID0gfmZyZXEsc2l6ZSA9IGMoNjAwLCA2MDApLHRpdGxlID0gIldpbGxpYW1NY0tpbmxleSAxICYgV29vZHJvd1dpbHNvbiAyICYgSmFtZXNCdWNoYW5hbiAxIixyb3RhdGlvblJhbmdlID0gYygtMSwgMSkpCmBgYAo8cD5FeGNlcHQgV2FzaGluZ3Rvbixmcm9tIE5vLjIgV2lsbGlhbSBNY0tpbmxleSh0ZXJtIDEpIHRvIE5vLjQgSmFtZXMgQnVjaGFuYW4odGVybSAxKSx0aGV5IGRpZG4ndCBldmVuIHVzZSBzZWNvbmQgcGVyc29uLkFkZCB0aGVpciB0aHJlZSdzIHNwZWVjaGVzIHRvIG1ha2UgdGhlIHdvcmRjbG91ZCx3ZSBjYW4gaGFyZGx5IGZpbmQgdGhlIHdvcmRzIGRlbW9uc3RyYXRpbmcgY2VudHJhbGl6YXRpb24gb2YgcG93ZXIsIGluc3RlYWQsdGhlcmUgYXJlIHdvcmRzIGxpa2UgImNvbmdyZXNzIiwiZmFpciIsImNpdmlsIiwibGlmZSIsc2hvd2luZyBtb3JlIGdlbnRsZSBlbW90aW9uLjwvcD4KPGg0PjQuMiBUb3AgdGVuIHVzaW5nIGZpcnN0IHBlcnNvbiBwbHVyYWwgZm9ybTwvaDQ+CgorIHgtYXhpczpkaWZmZXJlbnQgcHJlc2lkZW50cworIHktYXhpczp0aGUgd2VpZ2h0IG9mIGEgY2VydGFpbiBraW5kIG9mIHBlcnNvbmFsIHByb25vdW4gYmVpbmcgdXNlZC4KCmBgYHtyfQplQmFyKG5ldzIsIH5uYW1lLCB+cHJvcG9ydGlvbiwgfnR5cGUpCmBgYAoKCmBgYHtyfQp0ZXN0PC1tYXRzb3J0W21hdHNvcnRbLCJuYW1lIl0gPT0gIkZyYW5rbGluRFJvb3NldmVsdCAzIixdCnRlc3QxPC1tYXRzb3J0W21hdHNvcnRbLCJuYW1lIl0gPT0gIlRoZW9kb3JlUm9vc2V2ZWx0IDEiLF0KdGVzdDI8LW1hdHNvcnRbbWF0c29ydFssIm5hbWUiXSA9PSAiQW5kcmV3SmFja3NvbiAxIixdCnRlc3QzPC1tYXRzb3J0W21hdHNvcnRbLCJuYW1lIl0gPT0gIkFicmFoYW1MaW5jb2xuIDIiLF0KdGVzdDQ8LW1hdHNvcnRbbWF0c29ydFssIm5hbWUiXSA9PSAiV2lsbGlhbU1jS2lubGV5IDIiLF0KdGVzdDU8LW1hdHNvcnRbbWF0c29ydFssIm5hbWUiXSA9PSAiRnJhbmtsaW5EUm9vc2V2ZWx0IDQiLF0KdGVzdDwtcmJpbmQodGVzdCx0ZXN0MSx0ZXN0Mix0ZXN0Myx0ZXN0NCx0ZXN0NSkKdGVzdDwtdGVzdFtvcmRlcihhcy5udW1lcmljKHRlc3RbLDNdKSxkZWNyZWFzaW5nID0gVCksXQp0ZXN0PC10ZXN0WzQwOjI2MzgsXQpkYXQ8LWRhdGEuZnJhbWUod29yZD10ZXN0Wywid29yZCJdLGZyZXE9dGVzdFssIm4iXSkKI3BhcihtZnJvdz1jKDEsMikpCmVXb3JkY2xvdWQoZGF0LCBuYW1ldmFyID0gfndvcmQsIGRhdGF2YXIgPSB+ZnJlcSxzaXplID0gYyg2MDAsIDYwMCksdGl0bGUgPSAiVE9QIDYgdXNpbmcgZmlyc3QgcGVyc29uIHBsdXJhbCBmb3JtIixyb3RhdGlvblJhbmdlID0gYygtMSwgMSkpCmBgYAoKPHA+Rm9yIHByZXNpZGVudHMgZnJlcXVlbnRseSB1c2luZyBmaXJzdCBwZXJzb24gcGx1cmFsIGZvcm0sIHRoZXJlIGV4aXN0cyBzaW1pbGFyIHBoZW5vbWVub24uRnJvbSBOby4xIEZyYW5rbGluIERSb29zZXZlbHQodGVybSAzKSB0byBOby42IEZyYW5rbGluIERSb29zZXZlbHQodGVybSA0KSx0aGV5IGFsc28gbWFrZSB0aGUgc3BlZWNoZXMgd2l0aG91dCB1c2luZyBzZWNvbmQgcGVyc29uLkFkZCB0aGVpciBzcGVlY2hlcyB0byBtYWtlIHRoZSB3b3JkY2xvdWQsd2UgZmluZCBzaW1pbGFyIHdvcmRzIHNob3dpbmcgZ2VudGxlIGVtb3Rpb24uPC9wPgoKPGg0PjQuMyBUb3AgdGVuIHVzaW5nIHNlY29uZCBwZXJzb248L2g0PgoKKyB4LWF4aXM6ZGlmZmVyZW50IHByZXNpZGVudHMKKyB5LWF4aXM6dGhlIHdlaWdodCBvZiBhIGNlcnRhaW4ga2luZCBvZiBwZXJzb25hbCBwcm9ub3VuIGJlaW5nIHVzZWQuCgpgYGB7cn0KZUJhcihuZXczLCB+bmFtZSwgfnByb3BvcnRpb24sIH50eXBlKQpgYGAKPGg0PjQuNCBUb3AgdGVuIHVzaW5nIHRoaXJkIHBlcnNvbjwvaDQ+CgorIHgtYXhpczpkaWZmZXJlbnQgcHJlc2lkZW50cworIHktYXhpczp0aGUgd2VpZ2h0IG9mIGEgY2VydGFpbiBraW5kIG9mIHBlcnNvbmFsIHByb25vdW4gYmVpbmcgdXNlZC4KCmBgYHtyfQplQmFyKG5ldzQsIH5uYW1lLCB+cHJvcG9ydGlvbiwgfnR5cGUpCmBgYAoKPGg0PjQuNSBFYWNoIHBlcnNvbmFsIHByb25vdW4ncyAiRmFuIENsdWIiIGZlYXR1cmUgOiBwb3NpdGl2ZT8gbmVnYXRpdmU/IDwvaDQ+CgpgYGB7cix3YXJuaW5nPUZ9CmRhdGEocG9zaXRpdmUud29yZHMpCmRhdGEobmVnYXRpdmUud29yZHMpCnNlbnRpbWVudF9hbmFseTwtZnVuY3Rpb24od29yZHMpCnsKICAgICAgc2NvcmU8LU5VTEwKICAgICAgIyBjb21wYXJlIHdvcmRzIHRvIHRoZSBkaWN0aW9uYXJpZXMgb2YgcG9zaXRpdmUgJiBuZWdhdGl2ZSB0ZXJtcwogICAgICBwb3NpdGl2ZS5tYXRjaGVzID0gbWF0Y2god29yZHMsIHBvc2l0aXZlLndvcmRzKQogICAgICBuZWdhdGl2ZS5tYXRjaGVzID0gbWF0Y2god29yZHMsIG5lZ2F0aXZlLndvcmRzKQogICAgICAjIGdldCB0aGUgcG9zaXRpb24gb2YgdGhlIG1hdGNoZWQgdGVybSBvciBOQQogICAgICAjIHdlIGp1c3Qgd2FudCBhIFRSVUUvRkFMU0UKICAgICAgcG9zaXRpdmVfbWF0Y2hlcyA9ICFpcy5uYShwb3NpdGl2ZS5tYXRjaGVzKQogICAgICBuZWdhdGl2ZV9tYXRjaGVzID0gIWlzLm5hKG5lZ2F0aXZlLm1hdGNoZXMpCiAgICAgIHNjb3JlID0gc3VtKHBvc2l0aXZlX21hdGNoZXMpIC0gc3VtKG5lZ2F0aXZlX21hdGNoZXMpIAogICAgICByZXR1cm4oc2NvcmUpCn0Kc2VudGlfdmVjPC1OVUxMCmZvcihpIGluIHNlcShucm93KGluYXVnLmxpc3QpKSkgewogIHRlc3Q8LW1hdHNvcnRbbWF0c29ydFssIm5hbWUiXT09cGFzdGUoaW5hdWcubGlzdCRGaWxlW2ldLGluYXVnLmxpc3QkVGVybVtpXSksIndvcmQiXQogIHNlbnRpX3ZlY1tpXTwtc2VudGltZW50X2FuYWx5KHRlc3QpCn0Kc3ZuYW1lPC1OVUxMCmZvcihpIGluIHNlcShucm93KGluYXVnLmxpc3QpKSkgewpzdm5hbWVbaV0gPC0gcGFzdGUoaW5hdWcubGlzdCRGaWxlW2ldLCBpbmF1Zy5saXN0JFRlcm1baV0pIH0KCiNzZW50aW1lbnQgdnMgcGVyc29uCnNlbnRpX21hdDwtY2JpbmQocHBuYW1lLHNlbnRpX3ZlYykKbjE8LW1hdGNoKHJvd25hbWVzKGRhdGExKSxwcG5hbWUpCm4yPC1tYXRjaChyb3duYW1lcyhkYXRhMikscHBuYW1lKQpuMzwtbWF0Y2gocm93bmFtZXMoZGF0YTMpLHBwbmFtZSkKbjQ8LW1hdGNoKHJvd25hbWVzKGRhdGE0KSxwcG5hbWUpCnNlbnRpX21hdDI8LWNiaW5kKHNlbnRpX21hdFtuMSwyXSxyZXAoImZpcnN0MSIsMTApKQpzZW50aV9tYXQyPC1yYmluZCggc2VudGlfbWF0MiAsIGNiaW5kKHNlbnRpX21hdFtuMiwyXSxyZXAoImZpcnN0MiIsMTApKSApCnNlbnRpX21hdDI8LXJiaW5kKCBzZW50aV9tYXQyICwgY2JpbmQoc2VudGlfbWF0W24zLDJdLHJlcCgic2Vjb25kIiwxMCkpICkKc2VudGlfbWF0MjwtcmJpbmQoIHNlbnRpX21hdDIgLCBjYmluZChzZW50aV9tYXRbbjQsMl0scmVwKCJ0aGlyZCIsMTApKSApCmNvbG5hbWVzKHNlbnRpX21hdDIpPC1jKCJzZW50aW1lbnRhbF9zY29yZXMiLCJwZXJzb25hbF9wcm9uIikKZGF0PC1kYXRhLmZyYW1lKHNlbnRpX21hdDIpCnAgPC0gZ2dwbG90KGRhdCwgYWVzKHBlcnNvbmFsX3Byb24sIGFzLm51bWVyaWMoc2VudGltZW50YWxfc2NvcmVzKSkpCnAgKyBnZW9tX2JveHBsb3QoKQpgYGAKCjxwPkFjY29yZGluZyB0byB0aGUgcGxvdCwgRmlyc3QgcGVyc29uIHBsdXJhbCdzICJGYW4gQ2x1YiIgdGVuZCB0byBiZSBtb3JlIG5lZ2F0aXZlLHdoaWxlIHRoZSB0aGlyZCBwZXJzb24gZm9ybSdzICJGYW4gQ2x1YiIgc2VlbSB0byBiZSBtb3JlIHBvc2l0aXZlLiBCdXQgdGhlcmUgaXMgbm8gb2J2aW91cyBkaWZmZXJlbmNlcy48L3A+Cgo8aDQ+NC42IEVhY2ggcGVyc29uYWwgcHJvbm91bidzICJGYW4gQ2x1YiIgZmVhdHVyZSA6IGF2ZXJhZ2Ugb2Ygd29yZCB1c2luZyB0aW1lcz8gPC9oND4KYGBge3Isd2FybmluZz1GfQojYXZnIHRpbWUgdnMgcGVyc29uCmF2Z19tYXQ8LW1hdHJpeChucm93ID0gbnJvdyhpbmF1Zy5saXN0KSxuY29sID0gMikKYXZnX21hdFssMV08LXBwbmFtZQpmb3IoaSBpbiBzZXEobnJvdyhpbmF1Zy5saXN0KSkpIHsKICB0ZXN0PC1tYXRzb3J0W21hdHNvcnRbLCJuYW1lIl09PXBhc3RlKGluYXVnLmxpc3QkRmlsZVtpXSxpbmF1Zy5saXN0JFRlcm1baV0pLF0KICBhdmdfbWF0W2ksMl08LXN1bShhcy5udW1lcmljKHRlc3RbLDNdKSkvbnJvdyh0ZXN0KQp9CnNlbnRpX21hdDM8LWNiaW5kKGF2Z19tYXRbbjEsMl0scmVwKCJmaXJzdDEiLDEwKSkKc2VudGlfbWF0MzwtcmJpbmQoIHNlbnRpX21hdDMgLCBjYmluZChhdmdfbWF0W24yLDJdLHJlcCgiZmlyc3QyIiwxMCkpICkKc2VudGlfbWF0MzwtcmJpbmQoIHNlbnRpX21hdDMgLCBjYmluZChhdmdfbWF0W24zLDJdLHJlcCgic2Vjb25kIiwxMCkpICkKc2VudGlfbWF0MzwtcmJpbmQoIHNlbnRpX21hdDMgLCBjYmluZChhdmdfbWF0W240LDJdLHJlcCgidGhpcmQiLDEwKSkgKQpjb2xuYW1lcyhzZW50aV9tYXQzKTwtYygid29yZF9hdmdfdGltZSIsInBlcnNvbmFsX3Byb24iKQpkYXQ8LWRhdGEuZnJhbWUoc2VudGlfbWF0MykKcCA8LSBnZ3Bsb3QoZGF0LCBhZXMocGVyc29uYWxfcHJvbiwgYXMubnVtZXJpYyh3b3JkX2F2Z190aW1lKSkpCnAgKyBnZW9tX2JveHBsb3QoKQpgYGAKPHA+QWNjb3JkaW5nIHRvIHRoZSBwbG90LCBGaXJzdCBwZXJzb24gcGx1cmFsJ3MgIkZhbiBDbHViIiB0ZW5kIHRvIHVzZSB0aGUgc2FtZSB3b3JkcyBmb3IgbGVzcyB0aW1lcyx0aGUgbWVkaWFuIGlzIGFib3V0IDEyIHRpbWVzO3doaWxlIHRoZSB0aGlyZCBwZXJzb24gZm9ybSdzICJGYW4gQ2x1YiIgdXNpbmcgdGhlIHNhbWUgd29yZHMgZm9yIG1vcmUgdGltZXMsdGhlIG1lZGlhbiBpcyBhYm91dCAyNyB0aW1lcy4gPC9wPgoKPGgzPjxmb250IGZhY2U9IlRpbWVzIE5ldyBSb21hbiI+UGFydCA1IC0gV2hhdCBhcmUgdGhleSB0YWxraW5nL2ZlZWxpbmcgdXNpbmcgcGVyc29uYWwgcHJvbm91biA/IDwvZm9udD48L2gzPgoKPHA+SW4gdGhpcyBwYXJ0LHdlIGdvIGEgbGl0dGxlIGRlZXBlciB0byBlYWNoIHNlbnRlbmNlcy5XaGF0J3MgdGhlIHdlaWdodCBvZiBwZXJzb25hbCBwcm9ub3VucyB1c2VkIGluIGVhY2ggc2VudGVuY2VzPyBJbiB0aG9zZSBzZW50ZW5jZXMsd2hhdCBhcmUgdGhleSB0YWxraW5nIGFib3V0IGFuZCB3aGF0IGVtb3Rpb24gYXJlIHRoZXkgdHJ5IHRvIGNvbnZleSx0aGVzZSBhcmUgd2hhdCB3ZSBjYXJlIGluIHRoaXMgcGFydC4KPHA+V2UgbWFpbmx5IG1ha2UgdHdvIHBsb3RzIHRvIGNvbXBhcmUuT25lIG9mIHRoZW0gaXMgc3RhY2tlZCBiYXIgcGxvdCxkZW1vbnN0cmF0aW5nIHRoZSBmb3VyIHByb3BvcnRpb25zIG9mIGZvdXIgcGVyc29uYWwgcHJvbm91bnMgZm9yIGVhY2ggc2VudGVuY2UgaW4gb25lIHNwZWVjaC5UaGUgc2Vjb25kIGlzIGFuIGFyZWEgcGxvdCxzaG93aW5nIGRpZmZlcmVudCBlbW90aW9ucyBmb3IgZWFjaCBzZW50ZW5jZSBpbiBvbmUgc3BlZWNoLjwvcD4KPHA+QWZ0ZXIgY2hlY2sgdGhlIHBsb3RzIGZvciBlYWNoIHByZXNpZGVudHMgb25lIGJ5IG9uZSxJIHdpbGwgc2hhcmUgdGhyZWUgZmluZGluZ3MgaGVyZS48L3A+Cgo8aDQ+PGZvbnQgZmFjZT0iVGltZXMgTmV3IFJvbWFuIj5GaW5kaW5nIDE6Zmlyc3Qgc2luZ3VsYXIgZm9ybSBhbHdheXMgY29tZSB3aXRoIHRydXN0IGFuZCBhbnRpY2lwYXRpb24uIDwvZm9udD48L2g0PgoKKyBHZW9yZ2UgV2FzaGluZ3RvbjogVGhlcmUgYXJlIDQgc2VudGVuY2VzIGluIGhpcyBzcGVlY2hlcyx3aXRoIDEsMiBhbmQgNCB1c2luZyBoaWdoIGZyZXF1ZW5jeSBvZiBmaXJzdCBwZXJzb24gc2luZ3VsYXIgcHJvbm91bixhbmQgdGhlIGVtb3Rpb25zIG9mIHRoZXNlIHNlbnRlbmNlcyBhcmUgbWFpbmx5IHRydXN0LgoKCmBgYHtyLHdhcm5pbmc9Rn0Kc2VudGVuX21hdDI8LW1lbHQoc2VudGVuX21hdCgyKSkKc2VuX2RhdDwtZGF0YS5mcmFtZShzZW50ZW5jZS5udW1iZXI9c2VudGVuX21hdDIkVmFyMSx0aW1lcz1zZW50ZW5fbWF0MiR2YWx1ZSxwZXJzb25hbF9wcm9ub3VuPXNlbnRlbl9tYXQyJFZhcjIsMikKc2VudGlfbWF0PC1yb3VuZChjb3VudF9lbW8oMilbLGMoMSwyLDQsNSw3LDgpXSwyKQpyb3duYW1lcyhzZW50aV9tYXQpPC1zZXEoMSxucm93KHNlbnRpX21hdCkpCnNlbnRpX21hdDI8LW1lbHQoc2VudGlfbWF0KQpzZW50aV9kYXQ8LWRhdGEuZnJhbWUoc2VudGVuY2VfbnVtYmVyPXNlbnRpX21hdDIkVmFyMSxzY29yZT1zZW50aV9tYXQyJHZhbHVlLHNlbnRpbWVudD1zZW50aV9tYXQyJFZhcjIpCgojcGFyKG1mcm93PWMoMSwyKSkKYTE8LWdncGxvdChzZW5fZGF0LGFlcyhzZW50ZW5jZS5udW1iZXIsdGltZXMsZmlsbD1wZXJzb25hbF9wcm9ub3VuKSkrZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiLHBvc2l0aW9uPSJzdGFjayIpK2dndGl0bGUoIiIpK2d1aWRlcyhmaWxsPWd1aWRlX2xlZ2VuZCh0aXRsZT1OVUxMKSkrIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiQmx1ZXMiKSsgeGxhYigic2VudGVuY2UgbnVtYmVyIikKI2IxPC1nZ3Bsb3Qoc2VudGlfZGF0LCBhZXMoeCA9IHNlbnRlbmNlX251bWJlciwgeSA9IHNjb3JlLCBmaWxsID0gc2VudGltZW50KSkgKwojICBnZW9tX2FyZWEoKSAKIyArIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiUmRCdSIsIGJyZWFrcyA9IHJldihjKGZhY3RvcihzZW50aW1lbnQpKSkpCiNiMTwtZ2dwbG90KHNlbnRpX2RhdCxhZXMoeCA9IHNlbnRlbmNlX251bWJlciwgeSA9IHNjb3JlLCBmaWxsID0gc2VudGltZW50KSkrZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiLHBvc2l0aW9uPSJzdGFjayIpK2dndGl0bGUoIiIpK2d1aWRlcyhmaWxsPWd1aWRlX2xlZ2VuZCh0aXRsZT1OVUxMKSkKI2dyaWQuYXJyYW5nZShhMSxiMSxucm93PTIpCmExCmBgYAoKCmBgYHtyfQplQXJlYShzZW50aV9tYXQpCiNmaW5kIHRvcGljcwojdGVzdDwtdG9waWNfd2MoMiwxKQojdGVzdDwtdGVzdFs3OjY1LF0KI2RhdDwtZGF0YS5mcmFtZSh3b3JkPXRlc3RbLCJ3b3JkIl0sZnJlcT10ZXN0WywibiJdKQojZVdvcmRjbG91ZChkYXQsIG5hbWV2YXIgPSB+d29yZCwgZGF0YXZhciA9IH5mcmVxLHNpemUgPSBjKDYwMCwgNjAwKSx0aXRsZSA9ICJHZW9yZ2UgV2FzaGluZ3RvbiAmIGZpc3QgcGVyc29uIHNpbmd1bGFyIixyb3RhdGlvblJhbmdlID0gYygtMSwgMSkpCmBgYApbZm9yIHRoZSBhcmVhIHBsb3RdCgp4LWF4aXM6c2VudGVuY2UgbnVtYmVyCgp5LWF4aXM6dGhlIHdlaWdodCBvZiBhIGNlcnRhaW4ga2luZCBvZiBlbW90aW9uIGJlaW5nIGRldGVjdGVkLgoKKyBXaWxsaWFtIE1jS2lubGV5OiBUaGUgc2VudGVuY2VzIHVzaW5nIGZpcnN0IHBlcnNvbiBzaW5ndWxhciBwcm9ub3VuIGZyZXF1ZW50bHkgYWxzbyBjb250YWlucyB0cnVzdCBlbW90aW9uLgoKCmBgYHtyfQpzZW50ZW5fbWF0MjwtbWVsdChzZW50ZW5fbWF0KDI4KSkKc2VuX2RhdDwtZGF0YS5mcmFtZShzZW50ZW5jZS5udW1iZXI9c2VudGVuX21hdDIkVmFyMSx0aW1lcz1zZW50ZW5fbWF0MiR2YWx1ZSxwZXJzb25hbF9wcm9ub3VuPXNlbnRlbl9tYXQyJFZhcjIsMikKc2VudGlfbWF0PC1yb3VuZChjb3VudF9lbW8oMjgpWyxjKDEsMiw0LDUsNyw4KV0sMikKcm93bmFtZXMoc2VudGlfbWF0KTwtc2VxKDEsbnJvdyhzZW50aV9tYXQpKQpzZW50aV9tYXQyPC1tZWx0KHNlbnRpX21hdCkKc2VudGlfZGF0PC1kYXRhLmZyYW1lKHNlbnRlbmNlX251bWJlcj1zZW50aV9tYXQyJFZhcjEsc2NvcmU9c2VudGlfbWF0MiR2YWx1ZSxzZW50aW1lbnQ9c2VudGlfbWF0MiRWYXIyKQoKI3BhcihtZnJvdz1jKDEsMikpCmExPC1nZ3Bsb3Qoc2VuX2RhdCxhZXMoc2VudGVuY2UubnVtYmVyLHRpbWVzLGZpbGw9cGVyc29uYWxfcHJvbm91bikpK2dlb21fYmFyKHN0YXQ9ImlkZW50aXR5Iixwb3NpdGlvbj0ic3RhY2siKStnZ3RpdGxlKCIiKStndWlkZXMoZmlsbD1ndWlkZV9sZWdlbmQodGl0bGU9TlVMTCkpKyBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIkJsdWVzIikrIHhsYWIoInNlbnRlbmNlIG51bWJlciIpCiNiMTwtZ2dwbG90KHNlbnRpX2RhdCwgYWVzKHggPSBzZW50ZW5jZV9udW1iZXIsIHkgPSBzY29yZSwgZmlsbCA9IHNlbnRpbWVudCkpICsKIyAgZ2VvbV9hcmVhKCkgCiMgKyBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlJkQnUiLCBicmVha3MgPSByZXYoYyhmYWN0b3Ioc2VudGltZW50KSkpKQojYjE8LWdncGxvdChzZW50aV9kYXQsYWVzKHggPSBzZW50ZW5jZV9udW1iZXIsIHkgPSBzY29yZSwgZmlsbCA9IHNlbnRpbWVudCkpK2dlb21fYmFyKHN0YXQ9ImlkZW50aXR5Iixwb3NpdGlvbj0ic3RhY2siKStnZ3RpdGxlKCIiKStndWlkZXMoZmlsbD1ndWlkZV9sZWdlbmQodGl0bGU9TlVMTCkpCiNncmlkLmFycmFuZ2UoYTEsYjEsbnJvdz0yKQphMQplQXJlYShzZW50aV9tYXQpCgojZmluZF9zZW4oMjgsMTM0KQojZmluZF9zZW4oMjgsMTM1KQojZmluZF9zZW4oMjgsMTM2KQojZmluZF9zZW4oMjgsMTM3KQojdGVzdDwtdG9waWNfd2MoMjgsMSlbMTo2MCxdCiN0ZXN0PC10ZXN0WzY6NjAsXQojZGF0PC1kYXRhLmZyYW1lKHdvcmQ9dGVzdFssIndvcmQiXSxmcmVxPXRlc3RbLCJuIl0pCiNlV29yZGNsb3VkKGRhdCwgbmFtZXZhciA9IH53b3JkLCBkYXRhdmFyID0gfmZyZXEsc2l6ZSA9IGMoNjAwLCA2MDApLHRpdGxlID0gIldpbGxpYW1NY0tpbmxleSAmIGZpc3QgcGVyc29uIHNpbmd1bGFyIixyb3RhdGlvblJhbmdlID0gYygtMSwgMSkpCmBgYAo8aDQ+PGZvbnQgZmFjZT0iVGltZXMgTmV3IFJvbWFuIj5GaW5kaW5nIDIgOmZpcnN0IHBsdXJhbCBmb3JtIGFsd2F5cyBjb252ZXkgcG9zaXRpdmUgZW1vdGlvbnMuPC9mb250PjwvaDQ+Cgo8cD5JbiB0aGUgZm9sbG93aW5nIHR3byBleGFtcGxlcyx0aGVyZSBpcyBsaWdodCBibHVlIHNob3dpbmcgdXNlIG9mIGZpcnN0IHBlcnNvbiBwbHVyYWwgZm9ybSBpbiB0aGUgZmlyc3QgcGxvdCxhbmQgaW4gdGhlIHNlY29uZCBwbG90LHdoZW4gd2UgZXhjbHVkZSBuZWdhdGl2ZSBlbW90aW9ucyB3ZSBjYW4gc2VlIHRoZSBwb3NpdGl2ZSBmbHVjdHVhdGlvbiBwYXR0ZXJuIGlzIG9uZS10by1vbmUgY29ycmVzcG9uZGVkIHdpdGggdGhlIGxpZ2h0IGJsdWUgaW4gcGxvdCAxLHdoaWNoIHN1Z2dlc3RzIGZpcnN0IHBsdXJhbCBmb3JtIGFsd2F5cyBjb252ZXkgcG9zaXRpdmUgZW1vdGlvbnMuPC9wPgoKCisgUmljaGFyZCBOaXhvbgoKYGBge3Isd2FybmluZz1GfQpzZW50ZW5fbWF0MjwtbWVsdChzZW50ZW5fbWF0KDQ1KSkKc2VuX2RhdDwtZGF0YS5mcmFtZShzZW50ZW5jZS5udW1iZXI9c2VudGVuX21hdDIkVmFyMSx0aW1lcz1zZW50ZW5fbWF0MiR2YWx1ZSxwZXJzb25hbF9wcm9ub3VuPXNlbnRlbl9tYXQyJFZhcjIpCgpwYXIobWZyb3c9Yyg0LDEpLCBtYXI9YygxLDAsMiwwKSwgYnR5PSJuIiwgeGF4dD0ibiIsIHlheHQ9Im4iLCBmb250Lm1haW49MSkKYTI8LWdncGxvdChzZW5fZGF0LGFlcyhzZW50ZW5jZS5udW1iZXIsdGltZXMsZmlsbD1wZXJzb25hbF9wcm9ub3VuKSkrZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiLHBvc2l0aW9uPSJzdGFjayIpK2dndGl0bGUoIiIpK2d1aWRlcyhmaWxsPWd1aWRlX2xlZ2VuZCh0aXRsZT1OVUxMKSkrCiAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJCbHVlcyIpKyB4bGFiKCJzZW50ZW5jZSBudW1iZXIiKQoKc2VudGlfbWF0Mzwtcm91bmQoY291bnRfZW1vKDQ1KVssYygxLDIsNCw1LDcsOCldLDIpCnJvd25hbWVzKHNlbnRpX21hdDMpPC1zZXEoMSxucm93KHNlbnRpX21hdDMpKQpzZW50aV9tYXQ0PC1tZWx0KHNlbnRpX21hdDMpCnNlbnRpX2RhdDI8LWRhdGEuZnJhbWUoc2VudGVuY2VfbnVtYmVyPXNlbnRpX21hdDQkVmFyMSxzY29yZT1zZW50aV9tYXQ0JHZhbHVlLHNlbnRpbWVudD1zZW50aV9tYXQ0JFZhcjIpCiNiMjwtZ2dwbG90KHNlbnRpX2RhdDIsIGFlcyh4ID0gc2VudGVuY2VfbnVtYmVyLCB5ID0gc2NvcmUsIGZpbGwgPSBzZW50aW1lbnQpKSArCiMgIGdlb21fYXJlYSgpIAojYjI8LWdncGxvdChzZW50aV9kYXQyLGFlcyh4ID0gc2VudGVuY2VfbnVtYmVyLCB5ID0gc2NvcmUsIGZpbGwgPSBzZW50aW1lbnQpKStnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIscG9zaXRpb249InN0YWNrIikrZ2d0aXRsZSgiIikrZ3VpZGVzKGZpbGw9Z3VpZGVfbGVnZW5kKHRpdGxlPU5VTEwpKQphMgoKYGBgCgpgYGB7cn0KYXBwbHkoc2VudGlfbWF0MywyLG1lYW4pCmVBcmVhKHNlbnRpX21hdDMpCiN0ZXN0PC10b3BpY193Yyg0NSwyKVsxOjYwLF0KI2RhdDwtZGF0YS5mcmFtZSh3b3JkPXRlc3RbLCJ3b3JkIl0sZnJlcT10ZXN0WywibiJdKQojZVdvcmRjbG91ZChkYXQsIG5hbWV2YXIgPSB+d29yZCwgZGF0YXZhciA9IH5mcmVxKQpgYGAKCltmb3IgdGhlIGFyZWEgcGxvdF0KCngtYXhpczpzZW50ZW5jZSBudW1iZXIKCnktYXhpczp0aGUgd2VpZ2h0IG9mIGEgY2VydGFpbiBraW5kIG9mIGVtb3Rpb24gYmVpbmcgZGV0ZWN0ZWQuCgorIEJhcmFjayBPYmFtYQoKYGBge3J9CnNlbnRlbl9tYXQyPC1tZWx0KHNlbnRlbl9tYXQoNTcpKQpzZW5fZGF0PC1kYXRhLmZyYW1lKHNlbnRlbmNlLm51bWJlcj1zZW50ZW5fbWF0MiRWYXIxLHRpbWVzPXNlbnRlbl9tYXQyJHZhbHVlLHBlcnNvbmFsX3Byb25vdW49c2VudGVuX21hdDIkVmFyMiwyKQpzZW50aV9tYXQ8LXJvdW5kKGNvdW50X2Vtbyg1NylbLGMoMSwyLDQsNSw3LDgpXSwyKQpyb3duYW1lcyhzZW50aV9tYXQpPC1zZXEoMSxucm93KHNlbnRpX21hdCkpCnNlbnRpX21hdDI8LW1lbHQoc2VudGlfbWF0KQpzZW50aV9kYXQ8LWRhdGEuZnJhbWUoc2VudGVuY2VfbnVtYmVyPXNlbnRpX21hdDIkVmFyMSxzY29yZT1zZW50aV9tYXQyJHZhbHVlLHNlbnRpbWVudD1zZW50aV9tYXQyJFZhcjIpCgojcGFyKG1mcm93PWMoMSwyKSkKYTE8LWdncGxvdChzZW5fZGF0LGFlcyhzZW50ZW5jZS5udW1iZXIsdGltZXMsZmlsbD1wZXJzb25hbF9wcm9ub3VuKSkrZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiLHBvc2l0aW9uPSJzdGFjayIpK2dndGl0bGUoIiIpK2d1aWRlcyhmaWxsPWd1aWRlX2xlZ2VuZCh0aXRsZT1OVUxMKSkrIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiQmx1ZXMiKSsgeGxhYigic2VudGVuY2UgbnVtYmVyIikKI2IxPC1nZ3Bsb3Qoc2VudGlfZGF0LCBhZXMoeCA9IHNlbnRlbmNlX251bWJlciwgeSA9IHNjb3JlLCBmaWxsID0gc2VudGltZW50KSkgKwojICBnZW9tX2FyZWEoKSAKIyArIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiUmRCdSIsIGJyZWFrcyA9IHJldihjKGZhY3RvcihzZW50aW1lbnQpKSkpCiNiMTwtZ2dwbG90KHNlbnRpX2RhdCxhZXMoeCA9IHNlbnRlbmNlX251bWJlciwgeSA9IHNjb3JlLCBmaWxsID0gc2VudGltZW50KSkrZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiLHBvc2l0aW9uPSJzdGFjayIpK2dndGl0bGUoIiIpK2d1aWRlcyhmaWxsPWd1aWRlX2xlZ2VuZCh0aXRsZT1OVUxMKSkKI2dyaWQuYXJyYW5nZShhMSxiMSxucm93PTIpCmExCmVBcmVhKHNlbnRpX21hdCkKI2ZpbmRfc2VuKDI4LDEzNCkKI2ZpbmRfc2VuKDI4LDEzNSkKI2ZpbmRfc2VuKDI4LDEzNikKI2ZpbmRfc2VuKDI4LDEzNykKYXBwbHkoc2VudGlfbWF0LDIsbWVhbikKI3Rlc3Q8LXRvcGljX3djKDM1LDIpWzE6NjAsXQojZGF0PC1kYXRhLmZyYW1lKHdvcmQ9dGVzdFssIndvcmQiXSxmcmVxPXRlc3RbLCJuIl0pCiNlV29yZGNsb3VkKGRhdCwgbmFtZXZhciA9IH53b3JkLCBkYXRhdmFyID0gfmZyZXEpCmBgYAoKPGg0Pjxmb250IGZhY2U9IlRpbWVzIE5ldyBSb21hbiI+RmluZGluZyAzIDogQW5nZXIgb2Z0ZW4gYmVnaW4gd2l0aCB0aGlyZCBwZXJzb24gZm9ybS48L2ZvbnQ+PC9oND4KCjxwPlRoZSB0aGlyZCBpcyBhYm91dCBhbmdlciB3aGljaCBpcyBhIGtpbmQgb2YgcmFyZSBlbW90aW9uIGluIHByZXNpZGVudHMgc3BlZWNoLkJ1dCBvbmNlIGl0IGFwcGVhciB0aGUgcmVkIHBhcnQgc2hvd2luZyBhbmdlcix0aGUgY29yZXNwb25kaW5nIHBhcnQgaXMgZGFyayBibHVlICx0aGF0IGlzIHNlbnRlbmNlIHdpdGggdGhpcmQgZm9ybS5XZSBjYW4gc2VlIHRoaXMgc2l0dWF0aW9uIGluIHRoZSBmb2xsb3dpbmcgdHdvIGV4YW1wbGVzLjwvcD4KCisgVWx5c3NlcyBTLkdyYW50CgoKYGBge3J9CnNlbnRlbl9tYXQyPC1tZWx0KHNlbnRlbl9tYXQoMjEpKQpzZW5fZGF0PC1kYXRhLmZyYW1lKHNlbnRlbmNlLm51bWJlcj1zZW50ZW5fbWF0MiRWYXIxLHRpbWVzPXNlbnRlbl9tYXQyJHZhbHVlLHBlcnNvbmFsX3Byb25vdW49c2VudGVuX21hdDIkVmFyMikKYTM8LWdncGxvdChzZW5fZGF0LGFlcyhzZW50ZW5jZS5udW1iZXIsdGltZXMsZmlsbD1wZXJzb25hbF9wcm9ub3VuKSkrZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiLHBvc2l0aW9uPSJzdGFjayIpK2dndGl0bGUoIiIpK2d1aWRlcyhmaWxsPWd1aWRlX2xlZ2VuZCh0aXRsZT1OVUxMKSkrIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiQmx1ZXMiKSsgeGxhYigic2VudGVuY2UgbnVtYmVyIikKc2VudGlfbWF0NTwtcm91bmQoY291bnRfZW1vKDIxKVssYygxLDIsNCw1LDcsOCldLDIpCnJvd25hbWVzKHNlbnRpX21hdDUpPC1zZXEoMSxucm93KHNlbnRpX21hdDUpKQpzZW50aV9tYXQ2PC1tZWx0KHNlbnRpX21hdDUpCnNlbnRpX2RhdDM8LWRhdGEuZnJhbWUoc2VudGVuY2VfbnVtYmVyPXNlbnRpX21hdDYkVmFyMSxzY29yZT1zZW50aV9tYXQ2JHZhbHVlLHNlbnRpbWVudD1zZW50aV9tYXQ2JFZhcjIpCmIzPC1nZ3Bsb3Qoc2VudGlfZGF0MyxhZXMoeCA9IHNlbnRlbmNlX251bWJlciwgeSA9IHNjb3JlLCBmaWxsID0gc2VudGltZW50KSkrZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiLHBvc2l0aW9uPSJzdGFjayIpK2dndGl0bGUoIiIpK2d1aWRlcyhmaWxsPWd1aWRlX2xlZ2VuZCh0aXRsZT1OVUxMKSkKI2IzPC1nZ3Bsb3Qoc2VudGlfZGF0MywgYWVzKHggPSBzZW50ZW5jZV9udW1iZXIsIHkgPSBzY29yZSwgZmlsbCA9IHNlbnRpbWVudCkpICsKIyAgZ2VvbV9hcmVhKCkgCmEzCmBgYAoKCmBgYHtyfQplQXJlYShzZW50aV9tYXQ1KQphcHBseShzZW50aV9tYXQ1LDIsbWVhbixuYS5ybT1UKQojdGVzdDwtdG9waWNfd2MoNTcsMilbMTo2MCxdCiNkYXQ8LWRhdGEuZnJhbWUod29yZD10ZXN0Wywid29yZCJdLGZyZXE9dGVzdFssIm4iXSkKI2VXb3JkY2xvdWQoZGF0LCBuYW1ldmFyID0gfndvcmQsIGRhdGF2YXIgPSB+ZnJlcSkKYGBgCltmb3IgdGhlIGFyZWEgcGxvdF0KCngtYXhpczpzZW50ZW5jZSBudW1iZXIKCnktYXhpczp0aGUgd2VpZ2h0IG9mIGEgY2VydGFpbiBraW5kIG9mIGVtb3Rpb24gYmVpbmcgZGV0ZWN0ZWQuCgoKKyBEd2lnaHQgRC5FaXNlbmhvd2VyCmBgYHtyfQpzZW50ZW5fbWF0MjwtbWVsdChzZW50ZW5fbWF0KDQzKSkKc2VuX2RhdDwtZGF0YS5mcmFtZShzZW50ZW5jZS5udW1iZXI9c2VudGVuX21hdDIkVmFyMSx0aW1lcz1zZW50ZW5fbWF0MiR2YWx1ZSxwZXJzb25hbF9wcm9ub3VuPXNlbnRlbl9tYXQyJFZhcjIpCmEzPC1nZ3Bsb3Qoc2VuX2RhdCxhZXMoc2VudGVuY2UubnVtYmVyLHRpbWVzLGZpbGw9cGVyc29uYWxfcHJvbm91bikpK2dlb21fYmFyKHN0YXQ9ImlkZW50aXR5Iixwb3NpdGlvbj0ic3RhY2siKStnZ3RpdGxlKCIiKStndWlkZXMoZmlsbD1ndWlkZV9sZWdlbmQodGl0bGU9TlVMTCkpKyBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIkJsdWVzIikrIHhsYWIoInNlbnRlbmNlIG51bWJlciIpCnNlbnRpX21hdDU8LXJvdW5kKGNvdW50X2Vtbyg0MylbLGMoMSwyLDQsNSw3LDgpXSwyKQpyb3duYW1lcyhzZW50aV9tYXQ1KTwtc2VxKDEsbnJvdyhzZW50aV9tYXQ1KSkKc2VudGlfbWF0NjwtbWVsdChzZW50aV9tYXQ1KQpzZW50aV9kYXQzPC1kYXRhLmZyYW1lKHNlbnRlbmNlX251bWJlcj1zZW50aV9tYXQ2JFZhcjEsc2NvcmU9c2VudGlfbWF0NiR2YWx1ZSxzZW50aW1lbnQ9c2VudGlfbWF0NiRWYXIyKQpiMzwtZ2dwbG90KHNlbnRpX2RhdDMsYWVzKHggPSBzZW50ZW5jZV9udW1iZXIsIHkgPSBzY29yZSwgZmlsbCA9IHNlbnRpbWVudCkpK2dlb21fYmFyKHN0YXQ9ImlkZW50aXR5Iixwb3NpdGlvbj0ic3RhY2siKStnZ3RpdGxlKCIiKStndWlkZXMoZmlsbD1ndWlkZV9sZWdlbmQodGl0bGU9TlVMTCkpCiNiMzwtZ2dwbG90KHNlbnRpX2RhdDMsIGFlcyh4ID0gc2VudGVuY2VfbnVtYmVyLCB5ID0gc2NvcmUsIGZpbGwgPSBzZW50aW1lbnQpKSArCiMgIGdlb21fYXJlYSgpIAphMwplQXJlYShzZW50aV9tYXQ1KQphcHBseShzZW50aV9tYXQ1LDIsbWVhbixuYS5ybT1UKQojdGVzdDwtdG9waWNfd2MoNTcsMilbMTo2MCxdCiNkYXQ8LWRhdGEuZnJhbWUod29yZD10ZXN0Wywid29yZCJdLGZyZXE9dGVzdFssIm4iXSkKI2VXb3JkY2xvdWQoZGF0LCBuYW1ldmFyID0gfndvcmQsIGRhdGF2YXIgPSB+ZnJlcSkKYGBgCgoKPGgzPjxmb250IGZhY2U9IlRpbWVzIE5ldyBSb21hbiI+UGFydCA2IC0gTmV4dCBzdGVwPC9mb250PjwvaDM+CgorIDxoND5Db2xsZWN0IG1vcmUgZGF0YSBmb3Igb3RoZXIgZm9ybWFsIHNwZWVjaGVzIHRvIGdhaW4gbW9yZSBjb252aW5jaW5nIGFuYWx5c2lzLjxoND4KKyA8aDQ+U21vb3RoIHRoZSBlbW90aW9uIGZ1bmN0aW9uIHRvIG1ha2UgaXQgbW9yZSBjbGVhci48aDQ+CgoK